Как улучшить производительность QGraphicsView в статической 2D-сцене с большим количеством элементов? (нельзя решить?)

Если правильно понять, QGraphicsView должен эффективно обрабатывать миллионы элементов.

В моем приложении у меня всего несколько тысяч, а производительность уже очень плохая. Когда View показывает всю сцену, масштабирование, hoverEnvents и любые другие вещи становятся невозможными.

Я пытался создать отношения родитель-потомок между элементами и разными флагами оптимизации, но все равно тот же результат. Очень надеюсь, что совершаю какую-то глупую ошибку, но после нескольких дней поиска пути решения проблемы так и не нашел решения.

Я был бы очень признателен за любую помощь!

Это воспроизводит мою проблему:

import sys
import random
from PyQt4.QtGui import * 

NO_INDEX = False
OPTIMIZE = False
ITEM_COORD_CACHE = False
ITEM_DEVICE_CACHE = False
NESTED_ITEMS = False


class TestItem(QGraphicsEllipseItem):
    def paint(self, painter, option, index):
        return QGraphicsEllipseItem.paint(self, painter, option, index)

    def hoverEnterEvent (self, e):
        self.setBrush(QBrush(QColor("orange")))

    def hoverLeaveEvent(self,e):
        self.setBrush(QBrush(None))

if __name__ == '__main__':
    n = int(sys.argv[1]) # Number of items. With 5000 I already
                           # have performance problems
    app = QApplication(sys.argv)
    scene = QGraphicsScene()

    # Populates scene
    prev = None
    for i in xrange(n):
        # Random geometry and position
        r1 = random.randint(10, 100)
        r2 = random.randint(10, 100)
        x = random.randint(0, 500)
        y = random.randint(0, 500)

        item = TestItem(x, y, r1*2, r2*2)
        item.setAcceptsHoverEvents(True)

        if NESTED_ITEMS: 
            # Creates a parent child structure among items
            if not prev:
                scene.addItem(item)
            else:
                item.setParentItem(prev)
            prev = item
        else:
            scene.addItem(item)

        if ITEM_COORD_CACHE:
            item.setCacheMode(QGraphicsItem.ItemCoordinateCache)
        elif ITEM_DEVICE_CACHE:
            item.setCacheMode(QGraphicsItem.DeviceCoordinateCache)

    # Creates View
    view = QGraphicsView(scene)
    # Sets basic Flags for nice rendering 
    view.setRenderHints(QPainter.Antialiasing or QPainter.SmoothPixmapTransform)

    if NO_INDEX:
        view.setItemIndexMethod(QGraphicsScene.NoIndex);

    if OPTIMIZE:
        view.setOptimizationFlags(QGraphicsView.DontAdjustForAntialiasing
                                  or QGraphicsView.DontClipPainter
                                  or QGraphicsView.DontSavePainterState)

    view.show()
    sys.exit(app.exec_())
  • Процессор Intel(R) Xeon(R) E5410 @ 2,33 ГГц
  • Корпорация nVidia G84 [Quadro FX 1700]
  • Убунту 9.04 64 бита
  • qt4 4.5.3
  • Python-qt4 4.6

person jhc    schedule 21.01.2011    source источник
comment
Я попробовал это с недавним PyQt5.7 и не заметил никакого влияния на производительность, несколько более быстрого процессора и 50 000 эллипсов. Я предполагаю, что Qt теперь лучше, и проблема, вероятно, будет решена по-другому, если она появится сейчас.   -  person Trilarion    schedule 12.10.2016


Ответы (1)


По сути, вы можете играть с режимами кэширования и обновления, а также с размером bsp-дерева сцены. Кроме того, это выступление на DevDays 2010 дает несколько советов и подсказок: depth" rel="nofollow">http://qt.nokia.com/developer/learning/online/talks/developerdays2010/tech-talks/qt-graphics-view-in-depth .

person e8johan    schedule 24.01.2011