[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