[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