Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Stopping Main Gui and worker thread before completion for PyQt5
Forum Updated to NodeBB v4.3 + New Features

Stopping Main Gui and worker thread before completion for PyQt5

Scheduled Pinned Locked Moved Unsolved General and Desktop
8 Posts 3 Posters 2.7k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • X Offline
    X Offline
    xyzz
    wrote on last edited by
    #1

    Hello. Recently started using PyQt5 and still learning.

    The code works. Here is the background and outline of the code:

    OS: Ubuntu Linux 18.04, bash shell

    Steps:

    1. Start the gui from the command line
    2. Gui pops up
    3. Press 'Start' button to begin execution of two *.py scripts.
    4. Based on examples online, created a worker QObject so the gui would not freeze while the long running loop continues.

    You can see the gui here:
    qCapture.PNG

    When pressing the STOP button, I want add the ability closing everything before completion if necessary: Closing the gui window, shutting down the ongoing processes created by the Worker thread. The equivalent of pressing Ctrl + c on the keyboard.

    Having a hard to time figuring it out. Any suggestions would help.

    Thanks.

    d.

    import sys
    import os
    from time import sleep
    import signal
    from PyQt5.QtCore import Qt
    from PyQt5 import QtCore, QtGui, QtWidgets
    from PyQt5.QtWidgets import (
        QApplication,
        QLabel,
        QMainWindow,
        QPushButton,
        QVBoxLayout,QProgressBar,
        QWidget,
    )
    from PyQt5.QtCore import QObject, QThread, pyqtSignal
    # Snip...
    
    # Step 1: Create a worker class
    class Worker(QObject):
        finished = pyqtSignal()
        progress = pyqtSignal(int)
    
        def run(self):
            """Long-running task."""
            for i in range(5):
                #sleep(1)
                os.system("./test_code01.py")
                self.progress.emit(i + 1)
            self.finished.emit()
    
    
    class Window(QMainWindow):
        signal.signal(signal.SIGINT,signal.SIG_DFL) 
        def __init__(self, parent=None):
            super().__init__(parent)
            self.progress_window()
    
        def progress_window(self):
            self.pbar_window=QWidget()
            self.pbar_window.setWindowTitle("QT Progressbar Example")
            self.pbar_window.setGeometry(432,232,320,200)
            self.pbar = QProgressBar(parent=self.pbar_window)
            self.pbar.setGeometry(50, 74, 200, 25)
            self.pbar.setValue(0)
            self.pbar_start_push = QtWidgets.QPushButton('Start',parent=self.pbar_window)
            self.pbar_start_push.setGeometry(50, 114, 55, 25)
            self.pbar_start_push.setEnabled(True)
            self.pbar_stop_push = QtWidgets.QPushButton('STOP',parent=self.pbar_window)
            self.pbar_stop_push.setGeometry(145, 114, 55, 25)
    
            self.pbar_window.show()
            self.pbar_start_push.clicked.connect(self.start_push)
            self.pbar_stop_push.clicked.connect(self.stopped_push)
        
        def start_push(self):
            print("started")
            self.pbar_start_push.setEnabled(False)
            self.runLongTask()
    
        def stopped_push(self):
            print("stopped")
            #print(self.thread.isRunning())   
            self.thread.exit()
            #print(self.thread.isRunning())
        def reportProgress(self, n):
            self.stepLabel.setText(f"Long-Running Step: {n}")
        # Snip...
        def runLongTask(self):
            # Step 2: Create a QThread object
            self.thread = QThread()
            # Step 3: Create a worker object
            self.worker = Worker()
            # Step 4: Move worker to the thread
            self.worker.moveToThread(self.thread)
            # Step 5: Connect signals and slots
            self.thread.started.connect(self.worker.run)
            self.worker.finished.connect(self.thread.quit)
            self.worker.finished.connect(self.worker.deleteLater)
            self.thread.finished.connect(self.thread.deleteLater)
            self.worker.progress.connect(self.reportProgress)
            # Step 6: Start the thread
            self.thread.start()
    
    app = QApplication(sys.argv)
    win = Window()
    #win.show()
    sys.exit(app.exec_())
    
    

    test_code01.py

    #!/usr/bin/python3
    import os
    
    i = 0
    while i < 100000000000000:
        i+=1
    os.system("./second_test_code02.py")
    
    

    second_test_code02.py

    #!/usr/bin/python3
    import os
    
    i = 0
    while i < 1000000000000000:
        i+=1
    
    
    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi and welcome to devnet,

      The cleanest way to do that is to design your long lasting operation so that they can be interrupted. That way you can raise a flag at any point in time and get them to stop more or less quickly depending on the size of the step they are currently executing.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • X Offline
        X Offline
        xyzz
        wrote on last edited by
        #3

        @SGaist said in Stopping Main Gui and worker thread before completion for PyQt5:

        Hi and welcome to devnet,

        Thank you for the welcoming. :

        The cleanest way to do that is to design your long lasting operation so that they can be interrupted. That way you can raise a flag at any point in time and get them to stop more or less quickly depending on the size of the step they are currently executing.

        I think that is my dilemma. Are flags only raised/checked after each iteration of a for/while loop? Given the size of the step can take about 5 minutes, are you saying I would have to wait 5 minutes before shutting down the long task with a flag/check? My hope is to stop the long task at any point in time by clicking the STOP pushbutton, like you can with a ctrl+c from a keyboard.

        d.

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          That completely depends on how you implement your operation. You can check the flag at each iteration, after each single step of the operation, etc. It's up to you to find the right balance.

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          X 1 Reply Last reply
          0
          • reineR Offline
            reineR Offline
            reine
            wrote on last edited by
            #5

            Did compile(pyinstaller.py) the module including Thread inside
            as nonwindowed executable,
            ran ???.exe (logging into log-file),
            in QtWindow app read log
            and ( addItems) into QListWidget frame.

            SGaistS 1 Reply Last reply
            0
            • reineR reine

              Did compile(pyinstaller.py) the module including Thread inside
              as nonwindowed executable,
              ran ???.exe (logging into log-file),
              in QtWindow app read log
              and ( addItems) into QListWidget frame.

              SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              @reine said in Stopping Main Gui and worker thread before completion for PyQt5:

              Did compile(pyinstaller.py) the module including Thread inside
              as nonwindowed executable,
              ran ???.exe (logging into log-file),
              in QtWindow app read log
              and ( addItems) into QListWidget frame.

              Hi,

              How is that related to this thread ?

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0
              • SGaistS SGaist

                That completely depends on how you implement your operation. You can check the flag at each iteration, after each single step of the operation, etc. It's up to you to find the right balance.

                X Offline
                X Offline
                xyzz
                wrote on last edited by xyzz
                #7

                @SGaist said in Stopping Main Gui and worker thread before completion for PyQt5:

                That completely depends on how you implement your operation. You can check the flag at each iteration, after each single step of the operation, etc. It's up to you to find the right balance.

                Thanks for your suggestions. I decided to convert the two scripts called in the Worker class into two functions of the Worker class instead.That made things much cleaner and easier to shut things down when necessary because it is viewed as one process, with one process ID.

                Thanks for helping me see things from a different point of view.

                d.

                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  You're welcome !

                  Since you have it working now, please mark the thread as solved using the "Topic Tools" button or the three dotted menu beside the answer you deem correct so that other forum users may know a solution has been found :-)

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  0

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved