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