4

我需要自定义一个 QGraphicsView 的绘制过程,所以我重写了 drawItems 方法,如下所示:

self.graphicsview.drawItems=self.drawer.drawItems

其中self.graphicsview是 QGraphicsView,并且self.drawer是带有方法的自定义类drawItems
在这种方法中,我检查了一些标志来决定如何绘制每个项目,然后调用item.paint,如下所示:

def drawItems(self, painter, items, options):
    for item in items:
        print "Processing", item
        # ... Do checking ...
        item.paint(painter, options, self.target)

self.target是 QGraphicsView 的 QGraphicsScene。
但是,一旦到达item.paint,它就会跳出循环 - 没有任何错误。如果我在绘画周围放置条件,并为每种可能的 QGraphicsItem 类型粘贴应该执行的代码(通过查看 Qt git-sources),一切正常。
虽然不是一个很好的解决方案......而且我不明白它是如何跳出循环的?

4

2 回答 2

3

绘制项目时会发生异常,但不会立即报告。在我的系统(PyQt 4.5.1,Python 2.6)上,当我对以下方法进行猴子补丁时,没有报告异常:

def drawItems(painter, items, options):
    print len(items)
    for idx, i in enumerate(items):
        print idx, i
        if idx > 5:
            raise ValueError()

输出:

45
0 <PyQt4.QtGui.QGraphicsPathItem object at 0x3585270>
1 <PyQt4.QtGui.QGraphicsSimpleTextItem object at 0x356ca68>
2 <PyQt4.QtGui.QGraphicsSimpleTextItem object at 0x356ce20>
3 <PyQt4.QtGui.QGraphicsSimpleTextItem object at 0x356cc88>
4 <PyQt4.QtGui.QGraphicsSimpleTextItem object at 0x356cc00>
5 <PyQt4.QtGui.QGraphicsSimpleTextItem object at 0x356caf0>
6 <PyQt4.QtGui.QGraphicsSimpleTextItem object at 0x356cb78>

但是,一旦我关闭应用程序,就会打印以下方法:

Exception ValueError: ValueError() in <module 'threading' from '/usr/lib/python2.6/threading.pyc'> ignored

我试过打印,但无论是在猴子补丁方法threading.currentThread()内部还是外部调用,它都会返回相同的线程。drawItems

在您的代码中,这可能是由于您将options(样式选项对象的列表)传递给单个项目而不是相应的选项对象。使用此代码应该会给您正确的结果:

def drawItems(self, painter, items, options):
    for item, option in zip(items, options):
        print "Processing", item
        # ... Do checking ...
        item.paint(painter, option, self.target)

另外,您说的self.target是场景对象。的文档paint()说:

该函数通常由 QGraphicsView 调用,以局部坐标绘制项目的内容。... widget 参数是可选的。如果提供,它指向正在绘制的小部件;否则为 0。对于缓存的绘画,小部件始终为 0。

类型是QWidget*. QGraphicsScene继承自QObject并且不是小部件,因此这也可能是错误的。

尽管如此,该异常根本没有报告,或者没有立即报告,这表明存在一些不正当行为,您应该联系维护者。

于 2009-07-17T13:58:52.113 回答
1

循环突然退出的原因是抛出了异常。Python 不处理它(没有try:块),所以它被传递给不知道 Python 异常的被调用(Qt 的 C++ 代码),所以它丢失了。

在循环周围添加一个 try/except ,您应该会看到发生这种情况的原因。

注意:从 Python 2.4 开始,您不应再以这种方式覆盖方法。

相反,您必须从 QGraphicsView 派生一个新类并将您的drawItems()方法添加到这个新类。这将正确替换原始方法。

不要忘记调用super()方法__init__!否则,您的对象将无法正常工作。

于 2009-07-17T13:20:47.603 回答