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

Baz Walter bazwal at ftml.net
Thu May 28 20:00:50 BST 2015


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