1
votes

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.

1

1 Answers

0
votes

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