PyQt:覆盖QGraphicsView.drawItems

2024-06-16 14:27:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要自定义QGraphicsView的绘图过程,因此我重写drawItems方法如下:

self.graphicsview.drawItems=self.drawer.drawItems

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

^{pr2}$

self.target是QGraphicsView的qgraphicscene。
但是,一旦它到达item.paint,它就会跳出循环——没有任何错误。如果我在画图的周围加上条件,并为每种可能类型的QGraphicsItem粘贴应该执行的代码(通过查看Qt-git源代码),那么一切都会成功。
但不是一个很好的解决办法。。。我不明白它怎么会脱离循环?在


Tags: 项目方法self绘图target过程标志绘制
2条回答

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

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

输出:

^{pr2}$

但是,关闭应用程序后,将打印以下方法:

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

我试着打印threading.currentThread(),但不管它是在monkey patcheddrawItems方法中调用还是在外部调用,它都返回相同的线程。在

在您的代码中,这很可能是因为您将options(这是一个样式选项对象的列表)传递给各个项而不是相应的option对象。使用此代码可以得到正确的结果:

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是场景对象。documentation for ^{}上写着:

This function, which is usually called by QGraphicsView, paints the contents of an item in local coordinates. ... The widget argument is optional. If provided, it points to the widget that is being painted on; otherwise, it is 0. For cached painting, widget is always 0.

类型是QWidget*QGraphicsSceneQObject继承而不是小部件,因此这很可能也是错误的。在

尽管如此,这个异常根本没有被报告,或者没有立即报告,这意味着某种恶意行为,您应该联系维护人员。在

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

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

注意:从Python2.4开始,就不应该再这样重写方法了。在

相反,您必须从QGraphicsView派生一个新类,并将您的drawItems()方法添加到这个新类中。这将适当地取代原来的方法。在

别忘了在__init__方法中调用super()!否则,对象将无法正常工作。在

相关问题 更多 >