0

What I am looking for is a way to stop a thread from the GUI. what I want to do is having a pause button, that every time it is clicked, the thread would be stopped.

It would look something like this (of course it is not the right syntax, is just to show an example:

if self.pause_button.clicked:
    #thread stops
if self.run_button.clicked:
    #thread starts again

Just to add more information, what my thread does is running a webssocket and returning the JSON value

David
  • 1
  • If you are using Python threads you could take a look at https://stackoverflow.com/q/33640283/10171966. – SebDieBln Jan 02 '22 at 13:03
  • It's not possible to pause the thread itself. All you can do is stop executing the relevant portion of the code that is running inside the thread. So, in abstract, something like: `while True: if not paused(): run_code()`. – ekhumoro Jan 02 '22 at 15:19
  • If you are using QThread, a brute force method might be to use sleep(), msleep(), or usleep() methods in a loop until the run_button is clicked. – bfris Jan 02 '22 at 18:59

1 Answers1

0

There is no way to pause Thread. However, You can imitate such a behavior by for example using Event from threading module. Personally I prefer toggling instead of using two buttons.

Here is simple code with Button implemented in PyQt6:

import sys
from threading import Thread, Event
from time import sleep

from PyQt6.QtWidgets import QApplication, QWidget, QPushButton


class Worker(Thread):

    def __init__(self, running_event: Event) -> None:
        self.running_event = running_event
        super().__init__()

    def run(self) -> None:
        """
        Worker is doing its job until running_event is set.
        :return: None
        """
        while self.running_event.wait():
            print("Working on something...")
            sleep(1)  # Imitate code execution


if __name__ == "__main__":
    app = QApplication(sys.argv)
    # Create and set running Event
    running_event = Event()
    running_event.set()

    widget = QWidget()
    toggle_button = QPushButton("Pause", widget)


    def toggle_running() -> None:
        """
        Toggle state of running event.
        :return: None
        """
        if running_event.is_set():
            running_event.clear()
            toggle_button.setText("Resume")
        else:
            running_event.set()
            toggle_button.setText("Pause")


    # Connect toggle_button to our toggle function
    toggle_button.clicked.connect(toggle_running)

    # Create and start worker
    worker = Worker(running_event)
    worker.setDaemon(True)
    worker.start()
    # Show widget and start application
    widget.show()
    app.exec()
Domarm
  • 2,360
  • 1
  • 5
  • 17