Hi I am developing a PyQt5 Application where the user can set a timer countdown. For updating the time label I use a QThread which emits a pyqtSignal every second in order to update the GUI/time label. This is my Code which uses QThread:
from PyQt5.QtCore import QThread, pyqtSignal, QObject import time
class Worker(QObject):
update = pyqtSignal()
stop = pyqtSignal()
class CountdownThread(QThread):
def __init__(self, time_left):
QThread.__init__(self)
self.time_signal = Worker()
self.time_left = time_left
self.is_running = True
def stop(self):
self.is_running = False
print(self.is_running)
def run(self):
while self.is_running:
self.time_left -= 1
time.sleep(1)
self.time_signal.update.emit()
if self.time_left == 0:
self.stop()
With a button click the user should be able to stop the countdown and reset the GUI:
...
def pressed_stop(self):
self.start_stop_btn.setText("Start")
self.start_stop_btn.clicked.connect(self.pressed_start)
self.worker.stop() # self.worker is the QThread
...
When I click on the button the button text certainly does change to "Start". But the time label keeps counting down. Printing the is_running
variable prints out False
when clicking the button and therefore executing the self.worker.stop()
function but keeps printing out True
in the while
loop of run()
.
Initializing the CountdownThread
is done here (after clicking start button):
...
def count_down(self):
self.worker = CountdownThread(self.time_left)
self.worker.time_signal.update.connect(self.update_time_label)
self.worker.time_signal.stop.connect(self.reset_timer)
self.worker.start()
...
Why doesn't this work? I am running this application on Mac OS Catalina 10.15.4.
As some might have noticed, I am using the same button object for starting and stopping the countdown. I forgot to add
self.start_stop_btn.disconnect()
otherwise it would always call the countdown function again
The thing happening here is that your QThread spends all of its time in a while(True)
loop, therefore it can never execute its stop()
method before reaching the end of the countdown by the loop.
I think a similar thread exists that adresses the same question.
What you can do to circumvent the issue is to include in your loop a way to fetch the stop flag from your main thread.
A few recommendations:
time.sleep(xx)
, I advise you to use QTimers for your application: they do the same but in a much easier way, and that would get rid of the while loop.the_QObject_extended_variable.moveToThread(the_QThread_variable)
Feel free to ask for examples if you need.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.