Model QProgressDialog jams when updated from separate thread
-
Using PySide2 I'm settings up a QThread to do a biggish job and update a QProgressDialog via signals. If the updates are emitted relatively slowly (once a second or so) this works fine, if they are more frequent (5-10 times a second) the QProgressDialog will stop updating at some point. If this happens the it will remain jammed for some time after the thread has finished its work. It will eventually come back to life and close properly.
This is an example of what I'm doing.
class SomeWidget(QtWidgets.QWidget): def __init__(self, parent=None): super(SomeWidget, self).__init__(parent) self.thread = QtCore.QThread() self.progress = QtWidgets.QProgressDialog("", "Cancel", 0, 100, self) self.progress.setWindowModality(QtCore.Qt.WindowModal) self.progress.setAutoClose(True) self.progress.setAutoReset(True) self.worker = Worker() self.worker.moveToThread(self.thread) self.worker.update_progress.connect(self.progress.setValue) self.worker.done.connect(self.work_done) self.thread.started.connect(self.worker.do_the_thing) self.thread.start() def work_done(self): self.thread.exit() print("Done") class Worker(QtCore.QObject): update_progress = QtCore.Signal(int) done = QtCore.Signal() def do_the_thing(self): for ii in range(1, 101): time.sleep(0.1) # Simulate work self.update_progress.emit(ii) self.done.emit()
This issue is unpredictable. It will jam at different points each time and occasionally it will make it through without stopping. If I do not set the QProgressBar modality to WindowModal, it works without issue. I assume that the modal progress bar affects the way signals are processed, but I'm not certain what the better way to hook this up would be.
-
Hi and welcome to devnet,
What version of PySide2 / PyQt5 are you using ?
On what OS ?
How did you install it ? -
Can you check if that also happens with the previous version ?
-
Yes, this looks like a regression. Please provide a complete minimal example so the developer will be able to more easily get started.
-
@JonB in the case at hand, the code is correct and the logic as well. The worker object approach makes it so that the signals and slots mechanism should work correctly. 5.15.0 being the latest release, the first thing to do is try the previous one to see if something broke as it's the case here.
One other thing that could be done is to implement the same code in C++ to see if it's binding or library related.