[PyQt] adding signalling to QGraphicsItems

Christopher M. Nahler christopher.nahler at papermodels.at
Mon Jul 5 10:38:10 BST 2010


On 01.07.2010 16:21, Phil Thompson wrote:
> 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
>    

I managed to implement it. I didnt have to use the scene signals but 
made the signalling subclass attribute work.

Instead of trying to send the whole MyRectangle I just send the 
variables I need (like a rect())
So now when I add a MyRectangle item to the scene I can connect the 
instance to the required slot and all is fine :-)

Thanks again



More information about the PyQt mailing list