[PyQt] adding signalling to QGraphicsItems

Phil Thompson phil at riverbankcomputing.com
Thu Jul 1 15:21:12 BST 2010


On Thu, 01 Jul 2010 16:10:32 +0200, "Christopher M. Nahler"
<christopher.nahler at papermodels.at> wrote:
> On 01.07.2010 12:29, Phil Thompson wrote:
>> On Thu, 01 Jul 2010 11:58:01 +0200, "Christopher M. Nahler"
>> <christopher.nahler at papermodels.at>  wrote:
>>    
>>> I want to add signalling functionality to scene items. In my case they
>>> are usually QGraphicsRectItems..
>>>
>>> I thought I could do this with deriving from QGraphicsObject but then I
>>> loose all the funtionality for the rectangle, handling pens and
brushes,
>>> shapes etc.
>>>
>>> Isn't it easier to just derive from QGraphicsRectItem and QObject? Or
>>> should I derive from QGraphicsRectItem and QGraphicsObject instead?
>>>      
>> Neither. You can't multiply inherit from more than one PyQt class.
>>
>>    
>>> Or are there any other ways to do this?
>>>      
>> Create a QObject subclass that implements your signals as an attribute
of
>> your QGraphicsRectItem.
>>
>> Phil
>>    
> 
> Thanks for the quick reply. I have tried to implement it that way but 
> stumbled over another problem I have in this case. I want to announce 
> that a MyRectangle was created (or has changed). When I want to add a 
> signalling object to my rectangle class I have to def it before. But 
> when I define the signal there I have to specify the data type which is 
> not yet defined.
> 
> 
> #!/usr/bin/env python
> # -*- coding: utf-8 -*-
> 
> from PyQt4.QtCore import *
> from PyQt4.QtGui import *
> 
> class Communicator(QObject):
>      MyRectangleCreated = pyqtSignal(MyRectangle) <-- MyRectangle not 
> defined yet!
> 
>      def __init(self):
>          super(Communicator, self).__init__(parent)
> 
> 
> class MyRectangle(QGraphicsRectItem):
> 
>      def __init__(self, rect=QRectF(0, 0, 0, 0), parent=None,
scene=None):
>          super(MyRectangle, self).__init__(parent, scene)
>          self.myCommunicator = Communicator()
>          self.myCommunicator.MyRectangleCreated.emit(self)

This can never work. You will always be emitting the signal before anything
has had a chance to connect to it.

> if __name__ == "__main__":
>      r = MyRectangle()
> 
> In genereal what I want to do is synchronize the QGraphicsItems from the 
> scene with a list of data objects. So when I create a graphics item a 
> data object in the data manager should be created and when I change a 
> graphics object the corresponding data block object should be updated.
> 
> BTW right now I have the handling of the events (which creates and 
> changes graphics items) in a widget derived from a view.
> 
> Any hints on the best approach for that?

You need some sort of rectangle manager (maybe the QGraphicsScene) that has
a method that will create a new MyRectangle instance and emit a signal that
it has done so.

Phil


More information about the PyQt mailing list