如何提高QGraphicsView在具有多个项的2D静态场景中的性能?(没有解决办法吗?)

0 投票
1 回答
2209 浏览
提问于 2025-04-16 10:22

如果我理解得没错,QGraphicsView应该能够高效地处理数百万个项目。

但在我的应用程序中,我只有几千个项目,性能已经非常糟糕。当视图显示整个场景时,缩放、悬停事件和其他操作都变得不可能。

我尝试在项目之间建立父子关系,并使用不同的优化选项,但结果还是一样。我真的希望我只是犯了什么愚蠢的错误,但经过几天寻找解决办法,我还是没有找到任何解决方案。

我非常感谢任何帮助!

以下是我遇到问题的复现代码:

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) CPU E5410 @ 2.33GHz
  • nVidia Corporation G84 [Quadro FX 1700]
  • Ubuntu 9.04 64位
  • qt4 4.5.3
  • python-qt4 4.6

1 个回答

1

简单来说,你可以调整的是缓存模式和更新模式,还有场景的bsp树的大小。此外,2010年开发者日的这段演讲也提供了一些提示和技巧:http://qt.nokia.com/developer/learning/online/talks/developerdays2010/tech-talks/qt-graphics-view-in-depth

撰写回答