[PyQt] Processing signals from a called method while the method executes

alanm me at alandmoore.com
Fri Jul 2 20:55:30 BST 2010


On Friday 02 July 2010 12:03:29 pm Jan Haag wrote:
> On 7/2/10 3:38 PM, alanm wrote:
> > On Friday 02 July 2010 1:17:06 am Andreas Pakulat wrote:
> >> Don't block the event-loop with your processor. The signals are
> >> delivered as you expect, but the widget is not redrawn with that
> >> message. The reason is that your processing blocks the Qt event loop and
> >> hence no painting is done.
> >> 
> >> Possible options to not block the event loop that long would be to use a
> >> QTimer to schedule each part of your processing after the next
> >> event-loop run. The other option would be moving the processing into a
> >> separate thread, you should only go this route after making familiar
> >> with multi-threading though.
> >> 
> >> Andreas
> > 
> > Thanks for the reply.  I don't think I understand, though.  I read in the
> > QTimer documentation where I can do a zero-millisecond timer to schedule
> > things after the next event run, but changing
> > 
> > sleep(10)
> > 
> > To:
> > 
> > QTimer.singleShot(0, lambda: sleep(10))
> > 
> > Seemed like it should do that.  It doesn't.  Apparently the
> > processor.process() method is still blocking.   Where am I going wrong
> > here?
> 
> What this actually does is to start a single-shot QTimer (timing out
> immediately) to run a callback during the next run of the event-loop;
> Thus far, you understood things correctly. However, _INSIDE_ this
> callback, you still set the GUI-thread and, as a consequence, the
> event-loop to sleep for 10 seconds. This is obviously not what you
> wanted... A better idea would be to call
> 
> QTimer.singleShot(10000, your_actual_processing_callback)
> 
> which delivers a timeout event triggering your callback after 10 seconds
> (10000 ms).
> The difference is that a QTimer runs asynchronously in a thread by
> itself, while sleep runs synchronously in the thread it is called in,
> thus blocking the event loop which does the same.

I think I confused everyone with the sleep(10) calls; the intention wasn't to 
actually have a ten second delay, but just to have a place-holder for some 
real call that might take 10 seconds or more, such as a file copy, subprocess 
call, etc.

Anyway, I finally solved my problem using threads; by making processor 
subclass QThread instead of QObject, renaming "process()" to "run()" and 
connecting the gobutton to processor.start() I got the correct behavior.

Thanks for your response.


More information about the PyQt mailing list