[PyKDE] Re: Threading problem with PyQt4 and Macosx

Phil Thompson phil at riverbankcomputing.co.uk
Tue Feb 27 10:56:28 GMT 2007


On Monday 26 February 2007 11:47 pm, Matt Newell wrote:
> > > It seems that I need to work out how to find the thread affinity of a
> > > Python object...
> >
> > ...which doesn't seem possible. So I think it's a case of clarifying the
> > documentation...
>
> Shouldn't this be possible for python callable's that are members of a
> QObject derived python class?

Only if you specify the slot with SLOT().

> > If you connect to a SLOT() then the slot is executed in the thread as
> > described in the Qt documentation.
> >
> > If you connect to a Python callable then the slot is executed according
> > to the same rules with the additional proviso that a SLOT is created on
> > the fly in the thread in which the call to connect() is made.
>
> If the slot(python callable) is a member of a python class that is derived
> from QObject, then the PyQtProxy object created should then be moved to the
> same thread that the QObject is in, using QObject::moveToThread.  That way
> the slot is called in the same thread as the QObject, which follow the same
> behavior as qt.  The only exception will be when a python callable that is
> not a member of a QObject derived class is used, then it will be called in
> whatever thread the connect call is made.

While closer to the Qt behaviour, I think it means that the explanation gets 
too complicated. I think its better to say...

1. If the slot is a Python callable, it's executed in the thread that called 
connect().

2. If the slot is a Qt slot (specified with SLOT()) then it is executed in the 
receiver's thread.

If all you have is 1. (and the receiver is derived from QObject) but you want 
2. then convert the method to a Qt slot using pyqtSignature and use SLOT().

> > You can then get your sample-thread example working by either moving the
> > connect() call to the __init__() method, or by making the connection a
> > direct one (or an auto one). In the first case the slot will execute in
> > the main thread, and in the second it will execute in the sub-thread. As
> > the slot is updating the GUI then you want to do the former.
> >
> > Matt - does this explanation still mean that the GIL needs to be released
> > in QObject ctors etc? Or have I got 2 separate issues confused?
>
> They are 2 separate issues, but after reviewing the relevant qt code I'm
> not sure if it will be required to release the GIL for qobject ctors/dtors.
>  It may work to require the GIL to be *LOCKED* whenever calling qt code
> that can hold a qt lock while calling back into python code(emit calling
> qmetatype::construct is currently the only place I know of).
>
> I'm still not 100% sure about all this though, and I think there may be a
> way to eliminate the deadlock situation by a simple change to the qt code. 
> I need more time to think about it, it kind of makes my head hurt:)

Ok. For the moment I'll add the -g flag so that the GIL is always released to 
see if anybody complains. Shout if you come up with an idea that's more 
efficient but still correct.

Phil




More information about the PyQt mailing list