[PyQt] Subclass of QGraphicsObject does not have the correct class name listed in QGraphicsScene.items()

Luke Campagnola lcampagn at email.unc.edu
Mon Dec 5 23:01:25 GMT 2011


How about this:

from PyQt4 import QtCore, QtGui
import sip
class GObject(QtGui.QGraphicsObject):
    def boundingRect(self):
        return QtCore.QRectF(0, 0, 10, 10)
    def paint(self, p, *args):
        p.drawRect(self.boundingRect())

app = QtGui.QApplication([])
scene = QtGui.QGraphicsScene()
obj = GObject()
scene.addItem(obj)
items = scene.items(QtCore.QPointF(0,0))
objAddr = sip.unwrapinstance(sip.cast(obj, QtGui.QGraphicsItem))
itemAddr = sip.unwrapinstance(sip.cast(items[0], QtGui.QGraphicsItem))
print "Adresses match:", objAddr == itemAddr
print "QGraphicsObject matches:", obj is items[0]



On Mon, Dec 5, 2011 at 16:33, Phil Thompson <phil at riverbankcomputing.com> wrote:
> On Mon, 5 Dec 2011 12:24:57 -0500, Luke Campagnola
> <lcampagn at email.unc.edu>
> wrote:
>> Howdy Phil,
>> I'm running into this issue where QGraphicsScene.items() does not
>> return the correct python objects if the items are subclassed from
>> QGraphicsObject. Your response to this issue several months ago was:
>>
>> On Fri, May 20, 2011 at 11:46, Phil Thompson
>> <phil at riverbankcomputing.com> wrote:
>>> It's because QGraphicsObject inherits both QObject and QGraphicsItem.
>>> items() returns a list of QGraphicsItems which, for a QGraphicsObject,
>>> has
>>> a different C++ address than the original QGraphicsObject. PyQt doesn't
>>> recognise that the QGraphicsItem is a cast of the QGraphicsObject. I
>>> don't
>>> think there is anything I can (sensibly) do about this.
>>
>> The workaround I am using for this bug is to maintain a dictionary
>> that maps from the QtGui::QGraphicsItem memory address back to the
>> original python object. Looks something like:
>>     cache[ sip.unwrapinstance(sip.cast(item, QtGui.QGraphicsItem)) ] =
> item
>>
>> This works, but it's rather messy since every instance of
>> QGraphicsObject and QGraphicsWidget needs to register itself with this
>> cache. I presume PyQt already maintains a similar dictionary so that
>> it can translate between Qt's internal memory addresses and PyQt's
>> wrapper objects. Would it not be straightforward to implement my
>> workaround from within PyQt?
>
> Not straightforward, but certainly worth thinking about.
>
> Do you have something small I can use as a test case?
>
> Phil


More information about the PyQt mailing list