[PyQt] Cross-thread signal connections
Jason Voegele
jason at jvoegele.com
Fri Aug 22 19:29:06 BST 2008
Hi all,
I am embarking upon my first PyQt application and I've come across an
issue using cross-thread signal connections that I can't figure out,
and I'm hoping someone here can help me.
The application I'm working on consists of several long-running tasks
that I would like to have execute in the background without freezing
the GUI, and furthermore I would like to execute several tasks
concurrently. Therefore I have created a Task class to represent the
tasks, and an Executor class which manages executing the tasks in a
dynamically determined number of threads [1]. Task objects emit
signals for state changes (such as RUNNING, CANCELED, etc.) and also to
report progress.
The way I use these Tasks in my application is as follows:
1) Main (GUI) thread creates a bunch of Task objects.
2) Main thread connects signals of Task objects to slots of various
objects that live in the main thread.
3) Main thread submits each task to an Executor.
4) Executor creates a few threads. Each thread takes a Task, executes
it, and repeats until all Tasks have been executed.
5) As each Task is executing, it will emit its state change and progress
signals. Since the Task is executing in a background thread, its
signals are emitted from that thread.
Now the problem is that the main (GUI) thread is never receiving the
signals from the Tasks that are executing in the background threads. I
know that cross-thread signals require an event loop in the receiver,
and that of course is the case here. I think the problem is that the
signal/slot connections are made in the main thread in (2), but that
the signals are not emitted from the same thread in which the
signal/slot connections were made. It seems like once the Task is
executing in a separate thread, its existing signal/slot connections
are lost, or at least do not apply in the new thread. I've tried it
both with and without calling moveToThread on the Task object, and it
doesn't seem to make a difference.
Unfortunately, at the time when my application is creating the Task
objects and connecting to its signals, it has no idea what thread the
task will end up executing in.
Does anyone have any advice on how to make this scheme work? Thanks for
any help you can offer.
[1] This scheme is similar to the facilities offered by the new
QtConcurrent module, but since that module is not yet available in PyQt
I cannot use it. I also have other reasons not to use QtConcurrent for
this particular application, but I won't go into the details here.
--
Jason Voegele
The aim of science is to seek the simplest explanations of complex
facts. Seek simplicity and distrust it.
-- Whitehead.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part.
Url : http://www.riverbankcomputing.com/pipermail/pyqt/attachments/20080822/187c3914/attachment.bin
More information about the PyQt
mailing list