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. Waiting for another thread to continue (if needed) before starting the pipeline
Forum Updated to NodeBB v4.3 + New Features

Waiting for another thread to continue (if needed) before starting the pipeline

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 3 Posters 475 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.
  • S Offline
    S Offline
    sapvi
    wrote on last edited by sapvi
    #1

    I am getting a bit confused with QThreads, as I am new to signal-slot concept.

    I have the following situation: I have some pre-calculations that can be triggered by user before running the main pipeline. These pre-calculations are optional but, if triggered, they should be computed before running the main pipeline. However, if they are not triggered, main pipeline can be started without them. The main pipeline only starts by click of button, so it can also happen that the pre-calculations finished before user pressed the button.

    So, there are 3 cases:
    a) Did not select to use pre-calculations -> just run pipeline normally
    b) Selected to use pre-calculations & triggered them -> wait till finished -> then run pipeline
    c) Selected to use pre-calculations & triggered them & finished before user decided to run pipeline -> just run pipeline normally.

    I managed to make this MRE, which seems to almost do what I need. I am also not sure this is correct approach in general as it looks a bit over-engineered, but I do not see some simpler way to do it.

    Question: is this correct approach in general?

    import sys
    import time
    from PySide2.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QCheckBox
    from PySide2.QtCore import QThread, Signal, Slot
    
    
    class CalculationWorker(QThread):
        """Simulates additional calculations in a separate thread."""
    
        finished = Signal()
    
        def run(self):
            print("Starting additional calculations...")
            time.sleep(3)
            print("Additional calculations completed.")
            self.finished.emit()
    
    
    class MainUI(QWidget):
        def __init__(self):
            super().__init__()
    
            self.checkbox = QCheckBox("With Additional Calculations")
            self.run_button = QPushButton("Run Pipeline")
            self.start_calc_button = QPushButton("Start Additional Calculations")
    
            layout = QVBoxLayout()
            layout.addWidget(self.checkbox)
            layout.addWidget(self.start_calc_button)
            layout.addWidget(self.run_button)
            self.setLayout(layout)
    
            self.calc_done = True
            self.worker = None
            self.waiting_for_calculations = False
    
            self.run_button.clicked.connect(self.run_pipeline)
            self.start_calc_button.clicked.connect(self.start_additional_calculations)
    
        def run_pipeline(self):
            """Ensure additional calculations are complete before running."""
            if not self.checkbox.isChecked():
                print("Running pipeline WITHOUT additional calculations.")
                self.process_pipeline()
                return
    
            if self.calc_done:
                print("Running pipeline (calculations were already completed).")
                self.process_pipeline()
                return
    
            print(
                "Waiting for additional calculations to finish before running pipeline..."
            )
            self.waiting_for_calculations = True
            self.worker.finished.connect(self.on_calculations_done_for_pipeline)
    
        @Slot()
        def on_calculations_done_for_pipeline(self):
            """Called when calculations are done, but only if waiting for pipeline."""
            if self.waiting_for_calculations:
                print("Calculations done. Now running pipeline.")
                self.process_pipeline()
                self.waiting_for_calculations = False
    
        def start_additional_calculations(self):
            """Start additional calculations in a worker thread."""
            if self.worker and self.worker.isRunning():
                print("Calculations are already running...")
                return  # Already running, do nothing
    
            print("Starting additional calculations...")
            self.calc_done = False
            self.worker = CalculationWorker()
            self.worker.finished.connect(self.on_calculations_done)
            self.worker.start()
    
        @Slot()
        def on_calculations_done(self):
            """Called when calculations are completed."""
            self.calc_done = True
            print("Ready to run pipeline.")
    
        def process_pipeline(self):
            """Placeholder for actual pipeline execution."""
            print("*** Pipeline processing completed! ***")
    
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        window = MainUI()
        window.show()
        sys.exit(app.exec_())
    
    1 Reply Last reply
    0
    • C Offline
      C Offline
      ChrisW67
      wrote on last edited by
      #2

      Why is a thread even involved here?

      • Start program
      • Enable the calculation and main pipeline buttons
      • The user can simply press the main pipeline button to continue (case a).
      • If the user opts to do the pre-calculations then disable the main pipeline button, perhaps display a "working" cursor or the like, call the calculation routine (in the main thread) , and enable the button when the computation process completes. (Cases b and c)
      S 1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Hi,

        As an alternative to @ChrisW67 suggestion, pipelines are usually graphs or list of tasks so you could simply prepend that preprocess task if your users select the optional preprocess and be done with it. No need for complex threading or change of logic.

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

        S 1 Reply Last reply
        0
        • C ChrisW67

          Why is a thread even involved here?

          • Start program
          • Enable the calculation and main pipeline buttons
          • The user can simply press the main pipeline button to continue (case a).
          • If the user opts to do the pre-calculations then disable the main pipeline button, perhaps display a "working" cursor or the like, call the calculation routine (in the main thread) , and enable the button when the computation process completes. (Cases b and c)
          S Offline
          S Offline
          sapvi
          wrote on last edited by
          #4

          @ChrisW67 in the actual app, the use case is that pre-calculation create some objects that are then visualized in the GUI even without running the pipeline. But if pipeline is run, then these objects CAN be passed to pipeline if selected, or pipeline still can be run without them. The thread is mainly there not to freeze the other visualizations while these objects are calculated.

          1 Reply Last reply
          0
          • SGaistS SGaist

            Hi,

            As an alternative to @ChrisW67 suggestion, pipelines are usually graphs or list of tasks so you could simply prepend that preprocess task if your users select the optional preprocess and be done with it. No need for complex threading or change of logic.

            S Offline
            S Offline
            sapvi
            wrote on last edited by
            #5

            @SGaist as mentioned above in reply to @ChrisW67 (I cannot post several messages immediately as a new user), I am not sure there is a change to do it without a thread.
            The goal of the thread is to let user freely explore the other parts of GUI during this calculation. Result of this calculation are also visualized in GUI, so these pre-calculations and the pipeline can exist independently in the app, and only if some parameters are selected, they are combined (case b and c). I am not sure there is some way to achieve this non-blocking behavior of the GUI without making these calculations as a separate QThread.

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

              If you don't want to freeze your UI, then yes threading is required.
              Then, what you could do is that in the slot connected to the button starting the pipeline is to check the status of the pre calculation. If it's running, connect its finished signal to the function that actually start the pipeline, otherwise business as usual. Make it single shot, or disconnect it when calling the slot.

              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
              1

              • Login

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