[PyQt] setapi and itemChange , setParentItem related bug.
Phil Thompson
phil at riverbankcomputing.com
Mon Aug 13 16:02:03 BST 2012
On Sun, 12 Aug 2012 10:03:03 -0700 (PDT), Ryan Kim <ryan at moglue.com>
wrote:
> Hi.
>
> When I set sip.setapi('QVariant', 2) and reimplement itemChange
function
> of
>
> QGraphicsItem, setParentItem doesn't work.
>
> I read this issue has been dealt with on this mailing list, but I guess
> It's
> still there.
>
> Simple code to reproduce this behavior.
> ----------------------------------------------------------------------
> import sip
> sip.setapi('QVariant', 2)
>
> from PyQt4 import QtCore
> from PyQt4 import QtGui
> import sys
> class TestItem(QtGui.QGraphicsRectItem):
> def __init__(self,x,y,width,height,parent=None):
> super(TestItem, self).__init__(x,y,width,height,parent)
> def itemChange(self,change,value):
> return super(TestItem,self).itemChange(change,value)
> if __name__ == '__main__':
> app = QtGui.QApplication(sys.argv)
> view = QtGui.QGraphicsView()
> scene = QtGui.QGraphicsScene(0,0,1024,1024)
> view.setScene(scene)
> rect1 = TestItem(0,0,100,100)
> rect2 = TestItem(100,100,50,50)
> rect1.setFlag(QtGui.QGraphicsItem.ItemIsMovable,True)
> rect2.setFlag(QtGui.QGraphicsItem.ItemIsMovable,True)
> rect2.setParentItem(rect1)
> scene.addItem(rect1)
> scene.addItem(rect2)
> view.show()
> sys.exit(app.exec_())
> ----------------------------------------------------------------------
> Big rectangle is parent of small rectangle.
>
> But If you move big rectangle, child doesn't move along with it's
parent.
>
> if u comment out sip.setapi('QVariant', 2), it just works.
>
> Appreciate any kind of help.
The problem is that this invokes a conversion from TestItem to QVariant.
In order to preserve all the attributes of TestItem PyQt wraps it with an
internal C++ class that Qt knows nothing about which results in the
reparenting process failing. One solution might be to automatically treat
the TestItem as a QGraphicsItem (which Qt does know about) but that would
cause another set of problems.
In the absence of a general solution (I can't think of one) the workaround
is to use sip.cast()...
def itemChange(self, change, value):
result = super(TestItem, self).itemChange(change, value)
if isinstance(result, QtGui.QGraphicsItem):
result = sip.cast(result, QtGui.QGraphicsItem)
return result
Phil
More information about the PyQt
mailing list