QThread does not Wait()
Demosthenes Koptsis
demosthenesk at gmail.com
Thu Jul 1 17:46:33 BST 2021
Hello, i test Qthread and i made an example with a Form, Run, Stop
buttons and a progressbar.
I want to click Run button and start a thread and to click Stop button
and Wait the thread.
I try to implement a movetothread example but the wait fails.
Here is the code.
MainWindow.py
-------------------------
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'MainWindow.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(400, 138)
self.btnRun = QtWidgets.QPushButton(Form)
self.btnRun.setGeometry(QtCore.QRect(20, 20, 89, 25))
self.btnRun.setObjectName("btnRun")
self.btnStop = QtWidgets.QPushButton(Form)
self.btnStop.setGeometry(QtCore.QRect(20, 60, 89, 25))
self.btnStop.setObjectName("btnStop")
self.progressBar = QtWidgets.QProgressBar(Form)
self.progressBar.setGeometry(QtCore.QRect(20, 100, 371, 23))
self.progressBar.setProperty("value", 24)
self.progressBar.setObjectName("progressBar")
self.dial = QtWidgets.QDial(Form)
self.dial.setGeometry(QtCore.QRect(200, 20, 50, 64))
self.dial.setObjectName("dial")
self.lcdNumber = QtWidgets.QLCDNumber(Form)
self.lcdNumber.setGeometry(QtCore.QRect(260, 20, 64, 71))
self.lcdNumber.setObjectName("lcdNumber")
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Test Thread"))
self.btnRun.setText(_translate("Form", "Run"))
self.btnStop.setText(_translate("Form", "Stop"))
----------------------------------------
MoveToThread.py
----------------------------------------
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from MainWindow import *
import sys
import time
class SomeObject(QObject):
finished = pyqtSignal()
changed = pyqtSignal(int)
def __init__(self, parent=None, counter_start=0):
super(SomeObject, self).__init__(parent)
self.counter = counter_start
def long_running(self):
self.counter = 0
while self.counter <= 100:
time.sleep(0.3)
self.counter += 1
self.changed.emit(self.counter)
print(str(self.counter))
self.finished.emit()
class MainWindow(QWidget):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.ui = Ui_Form()
self.ui.setupUi(self)
self.center()
#Init progressBar
self.ui.progressBar.setValue(0)
#Buttons
self.ui.btnRun.clicked.connect(self.StartThread)
self.ui.btnStop.clicked.connect(self.WaitThread)
self.ui.dial.sliderMoved.connect(self.SetLCD)
#Init Thread
self.objThread = QThread()
self.obj = SomeObject()
self.obj.moveToThread(self.objThread)
self.obj.finished.connect(self.objThread.quit)
self.obj.changed.connect(self.SetProgressBarValue)
self.objThread.started.connect(self.obj.long_running)
def SetLCD(self):
self.ui.lcdNumber.display(self.ui.dial.value())
def WaitThread(self):
self.objThread.wait()
def StartThread(self):
self.objThread.start()
def SetProgressBarValue(self):
self.ui.progressBar.setValue(self.obj.counter)
def center(self):
# geometry of the main window
qr = self.frameGeometry()
# center point of screen
cp = QDesktopWidget().availableGeometry().center()
# move rectangle's center point to screen's center point
qr.moveCenter(cp)
# top left of rectangle becomes top left of window centering it
self.move(qr.topLeft())
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MainWindow()
# Disable maximize window button
w.setWindowFlags(Qt.WindowCloseButtonHint |
Qt.WindowMinimizeButtonHint)
w.show()
sys.exit(app.exec_())
----------------------------------------------
When i call WaitThread the emit of counter stops but the while loop
works after all
More information about the PyQt
mailing list