I have made an exact (i hope) Python version of your C++ code, i post it below.
The thing seems to be working ok, the progress bar is updated correctly and the main thread (form) remains responsive.
(I do not like the fact that i use 3 classes just to do that but anyway...)
So, we connect the propagate SIGNAl to the Emiter one and thus we get the SLOT setValue of the progress bar to be fired when the SIGNAL is sent.
In a previous version of mine, you have said that in the way i had wrote it was a little dangerous because we might not be sure from what thread the code will be executed.
As i study more closely your code (and my Python implementation of this), what make you sure that in this way the function will be called from the correct thread ?
Here is the code:
import sys
from PyQt4 import QtCore, QtGui
from calculatorform_ui import Ui_CalculatorForm
from ui_countNumbers import Ui_MainWindow
from time import sleep
def __init__(self):
def emitSignal(self, val):
self.emit(QtCore.SIGNAL("updateProgress(int)"), val)
class WorkerThread
(QtCore.
QThread): def __init__(self):
self.pstart = 0
self.pend = 0
def run(self):
e = Emiter()
propagate = QtCore.SIGNAL("propagate(int)")
QtCore.
QObject.
connect(e, QtCore.
SIGNAL("updateProgress(int)"), self, propagate
)
for x in range(self.pstart, self.pend):
sleep(1)
e.emitSignal(x)
def __init__(self, parent=None):
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
@QtCore.pyqtSignature("")
def on_start_clicked(self):
worker.pstart = count.ui.spFrom.value()
worker.pend = count.ui.spTo.value() + 1
self.ui.progress.setRange(worker.pstart, worker.pend)
worker.start()
def updateProgress(self, val):
self.ui.progress.setValue(val)
if __name__ == "__main__":
count = CountNumbersForm();
worker = WorkerThread();
QtCore.
QObject.
connect(worker, QtCore.
SIGNAL("propagate(int)"), count.
ui.
progress.
setValue, QtCore.
Qt.
QueuedConnection) count.show()
sys.exit(app.exec_())
import sys
from PyQt4 import QtCore, QtGui
from calculatorform_ui import Ui_CalculatorForm
from ui_countNumbers import Ui_MainWindow
from time import sleep
class Emiter(QtCore.QObject):
def __init__(self):
QtCore.QObject.__init__(self)
def emitSignal(self, val):
self.emit(QtCore.SIGNAL("updateProgress(int)"), val)
class WorkerThread(QtCore.QThread):
def __init__(self):
QtCore.QThread.__init__(self)
self.pstart = 0
self.pend = 0
def run(self):
e = Emiter()
propagate = QtCore.SIGNAL("propagate(int)")
QtCore.QObject.connect(e, QtCore.SIGNAL("updateProgress(int)"), self, propagate)
for x in range(self.pstart, self.pend):
sleep(1)
e.emitSignal(x)
class CountNumbersForm(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
@QtCore.pyqtSignature("")
def on_start_clicked(self):
worker.pstart = count.ui.spFrom.value()
worker.pend = count.ui.spTo.value() + 1
self.ui.progress.setRange(worker.pstart, worker.pend)
worker.start()
def updateProgress(self, val):
self.ui.progress.setValue(val)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
count = CountNumbersForm();
worker = WorkerThread();
QtCore.QObject.connect(worker, QtCore.SIGNAL("propagate(int)"), count.ui.progress.setValue, QtCore.Qt.QueuedConnection)
count.show()
sys.exit(app.exec_())
To copy to clipboard, switch view to plain text mode
I mean, if i emit entirely the Emit class and the like and replace WorkerThread class with this:
class WorkerThread
(QtCore.
QThread): def __init__(self):
self.pstart = 0
self.pend = 0
def run(self):
for x in range(self.pstart, self.pend):
sleep(1)
self.emit(QtCore.SIGNAL("updateProgress(int)"), x)
class WorkerThread(QtCore.QThread):
def __init__(self):
QtCore.QThread.__init__(self)
self.pstart = 0
self.pend = 0
def run(self):
for x in range(self.pstart, self.pend):
sleep(1)
self.emit(QtCore.SIGNAL("updateProgress(int)"), x)
To copy to clipboard, switch view to plain text mode
what do you think will go wrong ? I read PyQt4 docs and says that the mechanism is able to "Connections may be made across threads." Isn't it our occassion here and particularly because i use queued connections ?? (QtCore.Qt.QueuedConnection)
Thanks again!
Bookmarks