[PyQt] hang in pyqt5.7

Phil Thompson phil at riverbankcomputing.com
Wed Nov 23 15:38:55 GMT 2016


On 18 Nov 2016, at 10:12 pm, oliver <oliver.schoenborn at gmail.com> wrote:
> 
> I am exploring how deleteLater, connections, QObject trees and circular references interact (because of a bug in our pyqt 5.7 app -- I think it might be due to strong references between some qobjects). Just want to bring to people's attention a hard lesson learnt:  if you override disconnectNotify(self, method) from QObject, so that you can check when signals of self get disconnected, beware that self self.receivers() may cause hangs. I have the following code:
> 
> def disconnectNotify(self, method):
>     meth_name = bytes(method.name()).decode()
>     signal = getattr(self, meth_name)
>     num_receivers = self.receivers(signal)  # ***
> 
> which gets called because qobjectA.signal is connected to qobjectB.some_slot, and qobjectB gets destroyed (so Qt automatically disconnects signal). Oddly, the problem is the last line (***): when that line is commented out, I can run 10,000 tests without hanging; with it, test will hang about 1% of time.  
> 
> I must say, if there is one thing that I really wish in PyQt, it's ability to interrogate a signal for connections to find the slots (i.e. object methods and functions) connected to it. Of course in a bug-free program, you should never need this because the Observer pattern encourages annonymity of emitters and receivers, but once in a while it would be really nice to be able to check what is connected (because some connections get established only in some circumstances, and sometimes you need to check if a slot is still connected).

PyQt can only do things that Qt can do.

> Being able to do something like this when some_signal is a pyqtSignal(): 
> 
> assert self.some_signal.is_connected(some_object.slot)

You could try and connect using the UniqueConnection type. If it fails then it is already connected.

> assert self.some_signal.num_connections < 5

Look at QObject.receivers().

Phil


More information about the PyQt mailing list