[PyQt] converting old signal/slot to new signal/slot

C C coastalchaos at hotmail.co.uk
Fri May 29 10:07:40 BST 2015


Baz,

Thank you for such an illuminating post.

Having read the guide to asking a question I tried to keep the example as short as possible. 

I see that I haven't done anything to the QtCore.QCoreApplication.instance() but it doesn't play a part in the new command as the sender is the DatabaseProxy

At the moment I'm not sure of the answers to your questions. I'll battle on converting the signals to the new style and then see what works and what doesn't. I can see that it's not just going to be as straight forward as sorting out the signal/slots as I'm now not able to run other commands that were working on 4 but I think i'll need to bone up on the "Cooperative Multi-inheritance" section of the PyQt5.4.1 docs.

I'll still have the code working on PyQt4 on another machine so I'll be able to compare behaviour to make sure the conversion worked (or not) but taking your advice about the design decisions that I need to make it should be clearer once I've seen what I have broken. At the moment i'll take the path of least resistance that allows the software to work when I launch it. Then I can get into the main event loop.

I'm new to the Qt/PyQt and have basic python so it's a steep learning curve

Rob



On 28 May 2015, at 20:00, Baz Walter <bazwal at ftml.net> wrote:

> On 28/05/15 14:53, C C wrote:
>> The only thing I'm trying to work out is what happened to
>> QtCore.QCoreApplication.instance() in the new style? Do i need to
>> bring it back into play somehow? I'm just trying to understand the
>> old style in this instance so I can ensure that I port from 4 to 5
>> cleanly without breaking functionality.
> 
> With the old-style syntax, connect() operated as either an instance method, and worked like this:
> 
>     connect: (sender, SIGNAL) -> (SLOT)
> 
> or as a static method, and worked like this:
> 
>     connect: (sender, SIGNAL) -> (receiver, SLOT)
>     connect: (sender, SIGNAL) -> (python-callable)
> 
> In the first form, the receiver is implied, and will be the caller of connect, whereas in the second form the receiver is explicit, and the caller need not have any role in the connection (i.e. it's neither the sender nor the receiver).
> 
> Your example code is using the static form, and could be written in any of these ways:
> 
>    self.connect(sender, SIGNAL("databaseChanged()"), handler)
>    QObject.connect(sender, SIGNAL("databaseChanged()"), handler)
>    whatever.connect(sender, SIGNAL("databaseChanged()"), handler)
> 
> The new-style syntax inverts this functional approach to connecting signals, and makes it much more object-oriented. So signal-objects make explicit connections to callable-objects, and the semantics become:
> 
>    (sender.signal): connect -> (callable)
> 
> Your question was: what happened to QtCore.QCoreApplication.instance()? The answer to which is: nothing, because it is the sender, and it is still there. The only thing which has really gone is the intermediary object that performed the connection (i.e. self/QObject/whatever).
> 
> The lack of an intermediary means that the new-style syntax does not allow custom signals to be defined on the fly. The class of the sender must define the custom signal, which is then bound to the instance. (This is exactly the same mechanism that python itself uses to create bound methods - i.e. ones that automatically get a self argument).
> 
> In your particular case, this has forced you into a design decision. If you want the current code to continue working in the same way, you would need to create a subclass of QApplication and define a custom database-changed signal on that. Otherwise, you would have to define the signal on some other class, and have instances of that class become the sender (which is, I suppose, where your disappearing act might occur).
> 
> So far, you have not shown any (real, non-pseudo) code that emits the database-changed signal, so it's hard to advise whether changing the sender could have any adverse effects. How does the application instance get to know the status of the database that changed? When and where does it emit the signal? Why is a queued connection being used? What other objects need to connect to the signal(s) the application instance emits?
> 
> -- 
> Regards
> Baz Walter



More information about the PyQt mailing list