PyQt: How to update progress without freezing the GUI? PyQt: How to update progress without freezing the GUI? multithreading multithreading

PyQt: How to update progress without freezing the GUI?


If you want to use signals to indicate progress to the main thread then you should really be using PyQt's QThread class instead of the Thread class from Python's threading module.

A simple example which uses QThread, signals and slots can be found on the PyQt Wiki:

https://wiki.python.org/moin/PyQt/Threading,_Signals_and_Slots


Native python queues won't work because you have to block on queue get(), which bungs up your UI.

Qt essentially implements a queuing system on the inside for cross thread communication. Try this call from any thread to post a call to a slot.

QtCore.QMetaObject.invokeMethod()

It's clunky and is poorly documented, but it should do what you want even from from a non-Qt thread.

You can also use event machinery for this. See QApplication (or QCoreApplication) for a method named something like "post".

Edit: Here's a more complete example...

I created my own class based on QWidget. It has a slot that accepts a string; I define it like this:

@QtCore.pyqtSlot(str)def add_text(self, text):   ...

Later, I create an instance of this widget in the main GUI thread. From the main GUI thread or any other thread (knock on wood) I can call:

QtCore.QMetaObject.invokeMethod(mywidget, "add_text", QtCore.Q_ARG(str,"hello world"))

Clunky, but it gets you there.

Dan.


I recommend you to use Queue instead of signaling. Personally I find it a much more robust and understandable way of programming, because it's more synchronous.

Threads should get "jobs" from a Queue, and put back results on another Queue. Yet a third Queue can be used by the threads for notifications and messages, like errors and "progress reports". Once you structure your code this way, it becomes much simpler to manage.

This way, a single "job Queue" and "result Queue" can also be used by a group of worker threads, it routes all the information from the threads into the main GUI thread.