Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. How to Use Multithreading
QtWS25 Last Chance

How to Use Multithreading

Scheduled Pinned Locked Moved Solved Qt for Python
15 Posts 3 Posters 1.8k Views
  • 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.
  • V Offline
    V Offline
    vidyul
    wrote on last edited by vidyul
    #1

    Hello Guys, I am currently making a interactive GUI for user where I have to display live video feed from camera and some serial data coming from Arduino. Currently the live video feed comes from my USB camera and I have to show this along with the data simultaneously. I have seen videos for Q Thread and Video Display using push Button.

    My question is how can I achieve display the data and no delay video feed at the same time using multi-threading after pressing just a single button named 'VD Display Button'.

    I am using pyqt5

    jsulmJ 1 Reply Last reply
    0
    • V vidyul

      @jsulm so what I want to do is I press a button after pressing that button it should go to the method named suppose 'abc'.
      In method abc I need to perfrom continuous reading of data until stopped and at the same time update the display real time for the data that is coming.
      here is the sample code:
      #!/usr/bin/env python3

      import os, sys, time
      from PyQt5 import QtWidgets, QtCore
      from PyQt5.QtCore import QLibraryInfo, pyqtSignal, pyqtSlot, QUrl, QTimer, QTime, QDate, QThread
      from PyQt5.QtWidgets import QDialog, QApplication, QMainWindow
      from PyQt5.uic import loadUi
      from PyQt5.QtGui import QImage
      from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent

      os.environ["QT_QPA_PLATFORM_PLUGIN_PATH"] = QLibraryInfo.location(
      QLibraryInfo.PluginsPath
      )

      class Sample_UI(QDialog):
      def init(self):
      super(Sample_UI,self).init()
      loadUi('Sample_Update.ui',self)

          self.Reports_Table.setColumnWidth(0,250)
          
          self.label_4.setText('LOGIC_CONTROL')
          
          timer=QTimer(self)
          timer.timeout.connect(self.showTime)
          timer.start(1)
          self.Test_Button.clicked.connect(self.testing)
          self.Save_Button.clicked.connect(self.save_data)
      

      def logic(self):
      import logic_build_library
      self.abc=logic_build_library.class1()

          try:
              systat=self.abc.sys_status()
              if systat is not None:
                  self.label_12.setStyleSheet('background-color: green; color: black;')
              else:
                  self.label_12.setStyleSheet('background-color: red; color: black;')
          except Exception as e:
              self.label_12.setStyleSheet('background-color: red; color: black;')
      def showTime(self):
          currentTime = QTime.currentTime()
          today_date=QDate.currentDate()
          displayTxt = today_date.toString()+" "+currentTime.toString('hh:mm:ss')
          self.label_6.setText(displayTxt)
      def save_data(self):
          print('Data Saved!')
          login=Login()
          widget.setFixedWidth(360)
          widget.setFixedHeight(360)
          widget.addWidget(login)
          widget.setCurrentIndex(widget.currentIndex()+1)
      

      How can I continuously fetch data and display it at the same time?

      J.HilkJ Offline
      J.HilkJ Offline
      J.Hilk
      Moderators
      wrote on last edited by
      #5

      @vidyul let me chatgpt that for you:

      To continuously fetch data and update the display in real-time, you can use a separate thread to fetch the data and emit a signal every time new data is available. The main thread can then connect a slot to this signal to update the UI. Here’s a simplified example:

      class DataThread(QThread):
          data_signal = pyqtSignal(object)
      
          def run(self):
              while True:
                  data = self.fetch_data()  # replace with your data fetching logic
                  self.data_signal.emit(data)
                  time.sleep(1)  # sleep for a while to prevent high CPU usage
      
      class ATE_UI(QDialog):
          def __init__(self):
              super(ATE_UI,self).__init__()
              loadUi('ATE_Update.ui',self)
              
              self.Reports_Table.setColumnWidth(0,250)
              
              self.label_4.setText('Flight Mode: VTOL')
              
              timer=QTimer(self)
              timer.timeout.connect(self.showTime)
              timer.start(1)
              self.Test_Button.clicked.connect(self.start_fetching_data)
              self.Save_Button.clicked.connect(self.save_data)
      
              self.data_thread = DataThread()
              self.data_thread.data_signal.connect(self.update_display)
      
          def start_fetching_data(self):
              self.data_thread.start()
      
          def update_display(self, data):
              # update your display with the new data here
              pass
      
          # ... rest of your code ...
      
      

      In this example, pressing the Test_Button will start the DataThread, which fetches data in a loop until stopped. Every time new data is fetched, it emits a signal with the data, which is connected to the update_display slot in the main thread. This slot can then update the UI with the new data.

      Please replace self.fetch_data() with your actual data fetching logic and implement the update_display method to update your UI with the new data. Also, don’t forget to handle stopping the thread when necessary. You might want to add a stop button and connect it to a method that calls self.data_thread.terminate(). Be aware that terminating threads can be dangerous if not handled properly, so it’s better to have a mechanism in your thread to stop it gracefully. For example, you can use a QMutex and a flag to check whether the thread should stop or continue fetching data. If the flag is set, the thread can finish its current iteration and then stop itself by returning from the run method. This way, you can avoid abruptly stopping the thread and potentially leaving resources in an inconsistent state.

      Please note that this is a simplified example and might not cover all edge cases. Always make sure to handle exceptions and edge cases in your code to prevent crashes and ensure a smooth user experience. Also, keep in mind that updating the UI from a different thread is not safe, and you should always use signals and slots for communication between threads in Qt.


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      V 2 Replies Last reply
      2
      • V vidyul

        Hello Guys, I am currently making a interactive GUI for user where I have to display live video feed from camera and some serial data coming from Arduino. Currently the live video feed comes from my USB camera and I have to show this along with the data simultaneously. I have seen videos for Q Thread and Video Display using push Button.

        My question is how can I achieve display the data and no delay video feed at the same time using multi-threading after pressing just a single button named 'VD Display Button'.

        I am using pyqt5

        jsulmJ Offline
        jsulmJ Offline
        jsulm
        Lifetime Qt Champion
        wrote on last edited by
        #2

        @vidyul Not sure what exactly your question is.
        If you think you really need more than one thread (do you?) then start a second thread where you retrieve the video frames and forward these frames via signals/slots to UI thread to show them (it is not allowed to manipulate UI from other threads!). For serial communication there is really no need for another threads - it is also asynchronous in Qt like all other stuff.

        https://forum.qt.io/topic/113070/qt-code-of-conduct

        V 1 Reply Last reply
        0
        • jsulmJ jsulm

          @vidyul Not sure what exactly your question is.
          If you think you really need more than one thread (do you?) then start a second thread where you retrieve the video frames and forward these frames via signals/slots to UI thread to show them (it is not allowed to manipulate UI from other threads!). For serial communication there is really no need for another threads - it is also asynchronous in Qt like all other stuff.

          V Offline
          V Offline
          vidyul
          wrote on last edited by vidyul
          #3

          @jsulm so what I want to do is I press a button after pressing that button it should go to the method named suppose 'abc'.
          In method abc I need to perfrom continuous reading of data until stopped and at the same time update the display real time for the data that is coming.
          here is the sample code:
          #!/usr/bin/env python3

          import os, sys, time
          from PyQt5 import QtWidgets, QtCore
          from PyQt5.QtCore import QLibraryInfo, pyqtSignal, pyqtSlot, QUrl, QTimer, QTime, QDate, QThread
          from PyQt5.QtWidgets import QDialog, QApplication, QMainWindow
          from PyQt5.uic import loadUi
          from PyQt5.QtGui import QImage
          from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent

          os.environ["QT_QPA_PLATFORM_PLUGIN_PATH"] = QLibraryInfo.location(
          QLibraryInfo.PluginsPath
          )

          class Sample_UI(QDialog):
          def init(self):
          super(Sample_UI,self).init()
          loadUi('Sample_Update.ui',self)

              self.Reports_Table.setColumnWidth(0,250)
              
              self.label_4.setText('LOGIC_CONTROL')
              
              timer=QTimer(self)
              timer.timeout.connect(self.showTime)
              timer.start(1)
              self.Test_Button.clicked.connect(self.testing)
              self.Save_Button.clicked.connect(self.save_data)
          

          def logic(self):
          import logic_build_library
          self.abc=logic_build_library.class1()

              try:
                  systat=self.abc.sys_status()
                  if systat is not None:
                      self.label_12.setStyleSheet('background-color: green; color: black;')
                  else:
                      self.label_12.setStyleSheet('background-color: red; color: black;')
              except Exception as e:
                  self.label_12.setStyleSheet('background-color: red; color: black;')
          def showTime(self):
              currentTime = QTime.currentTime()
              today_date=QDate.currentDate()
              displayTxt = today_date.toString()+" "+currentTime.toString('hh:mm:ss')
              self.label_6.setText(displayTxt)
          def save_data(self):
              print('Data Saved!')
              login=Login()
              widget.setFixedWidth(360)
              widget.setFixedHeight(360)
              widget.addWidget(login)
              widget.setCurrentIndex(widget.currentIndex()+1)
          

          How can I continuously fetch data and display it at the same time?

          jsulmJ J.HilkJ 2 Replies Last reply
          0
          • V vidyul

            @jsulm so what I want to do is I press a button after pressing that button it should go to the method named suppose 'abc'.
            In method abc I need to perfrom continuous reading of data until stopped and at the same time update the display real time for the data that is coming.
            here is the sample code:
            #!/usr/bin/env python3

            import os, sys, time
            from PyQt5 import QtWidgets, QtCore
            from PyQt5.QtCore import QLibraryInfo, pyqtSignal, pyqtSlot, QUrl, QTimer, QTime, QDate, QThread
            from PyQt5.QtWidgets import QDialog, QApplication, QMainWindow
            from PyQt5.uic import loadUi
            from PyQt5.QtGui import QImage
            from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent

            os.environ["QT_QPA_PLATFORM_PLUGIN_PATH"] = QLibraryInfo.location(
            QLibraryInfo.PluginsPath
            )

            class Sample_UI(QDialog):
            def init(self):
            super(Sample_UI,self).init()
            loadUi('Sample_Update.ui',self)

                self.Reports_Table.setColumnWidth(0,250)
                
                self.label_4.setText('LOGIC_CONTROL')
                
                timer=QTimer(self)
                timer.timeout.connect(self.showTime)
                timer.start(1)
                self.Test_Button.clicked.connect(self.testing)
                self.Save_Button.clicked.connect(self.save_data)
            

            def logic(self):
            import logic_build_library
            self.abc=logic_build_library.class1()

                try:
                    systat=self.abc.sys_status()
                    if systat is not None:
                        self.label_12.setStyleSheet('background-color: green; color: black;')
                    else:
                        self.label_12.setStyleSheet('background-color: red; color: black;')
                except Exception as e:
                    self.label_12.setStyleSheet('background-color: red; color: black;')
            def showTime(self):
                currentTime = QTime.currentTime()
                today_date=QDate.currentDate()
                displayTxt = today_date.toString()+" "+currentTime.toString('hh:mm:ss')
                self.label_6.setText(displayTxt)
            def save_data(self):
                print('Data Saved!')
                login=Login()
                widget.setFixedWidth(360)
                widget.setFixedHeight(360)
                widget.addWidget(login)
                widget.setCurrentIndex(widget.currentIndex()+1)
            

            How can I continuously fetch data and display it at the same time?

            jsulmJ Offline
            jsulmJ Offline
            jsulm
            Lifetime Qt Champion
            wrote on last edited by
            #4

            @vidyul said in How to Use Multithreading:

            How can I continuously fetch data and display it at the same time?

            I have no idea how you fetch the data - you did not explain what camera and how you're accessing it. And regarding displaying: I already wrote that you can pass the data from the camera fetching thread to the UI thread using signals/slots.

            https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            0
            • V vidyul

              @jsulm so what I want to do is I press a button after pressing that button it should go to the method named suppose 'abc'.
              In method abc I need to perfrom continuous reading of data until stopped and at the same time update the display real time for the data that is coming.
              here is the sample code:
              #!/usr/bin/env python3

              import os, sys, time
              from PyQt5 import QtWidgets, QtCore
              from PyQt5.QtCore import QLibraryInfo, pyqtSignal, pyqtSlot, QUrl, QTimer, QTime, QDate, QThread
              from PyQt5.QtWidgets import QDialog, QApplication, QMainWindow
              from PyQt5.uic import loadUi
              from PyQt5.QtGui import QImage
              from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent

              os.environ["QT_QPA_PLATFORM_PLUGIN_PATH"] = QLibraryInfo.location(
              QLibraryInfo.PluginsPath
              )

              class Sample_UI(QDialog):
              def init(self):
              super(Sample_UI,self).init()
              loadUi('Sample_Update.ui',self)

                  self.Reports_Table.setColumnWidth(0,250)
                  
                  self.label_4.setText('LOGIC_CONTROL')
                  
                  timer=QTimer(self)
                  timer.timeout.connect(self.showTime)
                  timer.start(1)
                  self.Test_Button.clicked.connect(self.testing)
                  self.Save_Button.clicked.connect(self.save_data)
              

              def logic(self):
              import logic_build_library
              self.abc=logic_build_library.class1()

                  try:
                      systat=self.abc.sys_status()
                      if systat is not None:
                          self.label_12.setStyleSheet('background-color: green; color: black;')
                      else:
                          self.label_12.setStyleSheet('background-color: red; color: black;')
                  except Exception as e:
                      self.label_12.setStyleSheet('background-color: red; color: black;')
              def showTime(self):
                  currentTime = QTime.currentTime()
                  today_date=QDate.currentDate()
                  displayTxt = today_date.toString()+" "+currentTime.toString('hh:mm:ss')
                  self.label_6.setText(displayTxt)
              def save_data(self):
                  print('Data Saved!')
                  login=Login()
                  widget.setFixedWidth(360)
                  widget.setFixedHeight(360)
                  widget.addWidget(login)
                  widget.setCurrentIndex(widget.currentIndex()+1)
              

              How can I continuously fetch data and display it at the same time?

              J.HilkJ Offline
              J.HilkJ Offline
              J.Hilk
              Moderators
              wrote on last edited by
              #5

              @vidyul let me chatgpt that for you:

              To continuously fetch data and update the display in real-time, you can use a separate thread to fetch the data and emit a signal every time new data is available. The main thread can then connect a slot to this signal to update the UI. Here’s a simplified example:

              class DataThread(QThread):
                  data_signal = pyqtSignal(object)
              
                  def run(self):
                      while True:
                          data = self.fetch_data()  # replace with your data fetching logic
                          self.data_signal.emit(data)
                          time.sleep(1)  # sleep for a while to prevent high CPU usage
              
              class ATE_UI(QDialog):
                  def __init__(self):
                      super(ATE_UI,self).__init__()
                      loadUi('ATE_Update.ui',self)
                      
                      self.Reports_Table.setColumnWidth(0,250)
                      
                      self.label_4.setText('Flight Mode: VTOL')
                      
                      timer=QTimer(self)
                      timer.timeout.connect(self.showTime)
                      timer.start(1)
                      self.Test_Button.clicked.connect(self.start_fetching_data)
                      self.Save_Button.clicked.connect(self.save_data)
              
                      self.data_thread = DataThread()
                      self.data_thread.data_signal.connect(self.update_display)
              
                  def start_fetching_data(self):
                      self.data_thread.start()
              
                  def update_display(self, data):
                      # update your display with the new data here
                      pass
              
                  # ... rest of your code ...
              
              

              In this example, pressing the Test_Button will start the DataThread, which fetches data in a loop until stopped. Every time new data is fetched, it emits a signal with the data, which is connected to the update_display slot in the main thread. This slot can then update the UI with the new data.

              Please replace self.fetch_data() with your actual data fetching logic and implement the update_display method to update your UI with the new data. Also, don’t forget to handle stopping the thread when necessary. You might want to add a stop button and connect it to a method that calls self.data_thread.terminate(). Be aware that terminating threads can be dangerous if not handled properly, so it’s better to have a mechanism in your thread to stop it gracefully. For example, you can use a QMutex and a flag to check whether the thread should stop or continue fetching data. If the flag is set, the thread can finish its current iteration and then stop itself by returning from the run method. This way, you can avoid abruptly stopping the thread and potentially leaving resources in an inconsistent state.

              Please note that this is a simplified example and might not cover all edge cases. Always make sure to handle exceptions and edge cases in your code to prevent crashes and ensure a smooth user experience. Also, keep in mind that updating the UI from a different thread is not safe, and you should always use signals and slots for communication between threads in Qt.


              Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


              Q: What's that?
              A: It's blue light.
              Q: What does it do?
              A: It turns blue.

              V 2 Replies Last reply
              2
              • J.HilkJ J.Hilk

                @vidyul let me chatgpt that for you:

                To continuously fetch data and update the display in real-time, you can use a separate thread to fetch the data and emit a signal every time new data is available. The main thread can then connect a slot to this signal to update the UI. Here’s a simplified example:

                class DataThread(QThread):
                    data_signal = pyqtSignal(object)
                
                    def run(self):
                        while True:
                            data = self.fetch_data()  # replace with your data fetching logic
                            self.data_signal.emit(data)
                            time.sleep(1)  # sleep for a while to prevent high CPU usage
                
                class ATE_UI(QDialog):
                    def __init__(self):
                        super(ATE_UI,self).__init__()
                        loadUi('ATE_Update.ui',self)
                        
                        self.Reports_Table.setColumnWidth(0,250)
                        
                        self.label_4.setText('Flight Mode: VTOL')
                        
                        timer=QTimer(self)
                        timer.timeout.connect(self.showTime)
                        timer.start(1)
                        self.Test_Button.clicked.connect(self.start_fetching_data)
                        self.Save_Button.clicked.connect(self.save_data)
                
                        self.data_thread = DataThread()
                        self.data_thread.data_signal.connect(self.update_display)
                
                    def start_fetching_data(self):
                        self.data_thread.start()
                
                    def update_display(self, data):
                        # update your display with the new data here
                        pass
                
                    # ... rest of your code ...
                
                

                In this example, pressing the Test_Button will start the DataThread, which fetches data in a loop until stopped. Every time new data is fetched, it emits a signal with the data, which is connected to the update_display slot in the main thread. This slot can then update the UI with the new data.

                Please replace self.fetch_data() with your actual data fetching logic and implement the update_display method to update your UI with the new data. Also, don’t forget to handle stopping the thread when necessary. You might want to add a stop button and connect it to a method that calls self.data_thread.terminate(). Be aware that terminating threads can be dangerous if not handled properly, so it’s better to have a mechanism in your thread to stop it gracefully. For example, you can use a QMutex and a flag to check whether the thread should stop or continue fetching data. If the flag is set, the thread can finish its current iteration and then stop itself by returning from the run method. This way, you can avoid abruptly stopping the thread and potentially leaving resources in an inconsistent state.

                Please note that this is a simplified example and might not cover all edge cases. Always make sure to handle exceptions and edge cases in your code to prevent crashes and ensure a smooth user experience. Also, keep in mind that updating the UI from a different thread is not safe, and you should always use signals and slots for communication between threads in Qt.

                V Offline
                V Offline
                vidyul
                wrote on last edited by
                #6

                @J-Hilk thank you for the help. I have run a sample code and it is running, I will update here as solved when everything works fine.

                1 Reply Last reply
                1
                • V vidyul has marked this topic as solved on
                • J.HilkJ J.Hilk

                  @vidyul let me chatgpt that for you:

                  To continuously fetch data and update the display in real-time, you can use a separate thread to fetch the data and emit a signal every time new data is available. The main thread can then connect a slot to this signal to update the UI. Here’s a simplified example:

                  class DataThread(QThread):
                      data_signal = pyqtSignal(object)
                  
                      def run(self):
                          while True:
                              data = self.fetch_data()  # replace with your data fetching logic
                              self.data_signal.emit(data)
                              time.sleep(1)  # sleep for a while to prevent high CPU usage
                  
                  class ATE_UI(QDialog):
                      def __init__(self):
                          super(ATE_UI,self).__init__()
                          loadUi('ATE_Update.ui',self)
                          
                          self.Reports_Table.setColumnWidth(0,250)
                          
                          self.label_4.setText('Flight Mode: VTOL')
                          
                          timer=QTimer(self)
                          timer.timeout.connect(self.showTime)
                          timer.start(1)
                          self.Test_Button.clicked.connect(self.start_fetching_data)
                          self.Save_Button.clicked.connect(self.save_data)
                  
                          self.data_thread = DataThread()
                          self.data_thread.data_signal.connect(self.update_display)
                  
                      def start_fetching_data(self):
                          self.data_thread.start()
                  
                      def update_display(self, data):
                          # update your display with the new data here
                          pass
                  
                      # ... rest of your code ...
                  
                  

                  In this example, pressing the Test_Button will start the DataThread, which fetches data in a loop until stopped. Every time new data is fetched, it emits a signal with the data, which is connected to the update_display slot in the main thread. This slot can then update the UI with the new data.

                  Please replace self.fetch_data() with your actual data fetching logic and implement the update_display method to update your UI with the new data. Also, don’t forget to handle stopping the thread when necessary. You might want to add a stop button and connect it to a method that calls self.data_thread.terminate(). Be aware that terminating threads can be dangerous if not handled properly, so it’s better to have a mechanism in your thread to stop it gracefully. For example, you can use a QMutex and a flag to check whether the thread should stop or continue fetching data. If the flag is set, the thread can finish its current iteration and then stop itself by returning from the run method. This way, you can avoid abruptly stopping the thread and potentially leaving resources in an inconsistent state.

                  Please note that this is a simplified example and might not cover all edge cases. Always make sure to handle exceptions and edge cases in your code to prevent crashes and ensure a smooth user experience. Also, keep in mind that updating the UI from a different thread is not safe, and you should always use signals and slots for communication between threads in Qt.

                  V Offline
                  V Offline
                  vidyul
                  wrote on last edited by
                  #7

                  @J-Hilk I have marked it as correct answer. I just wanted to know it for my knowledge that Can I have more than 1 worker class inherited from Q Thread? And How can I achieve that? It can be useful for me in the future.

                  jsulmJ 1 Reply Last reply
                  0
                  • V vidyul

                    @J-Hilk I have marked it as correct answer. I just wanted to know it for my knowledge that Can I have more than 1 worker class inherited from Q Thread? And How can I achieve that? It can be useful for me in the future.

                    jsulmJ Offline
                    jsulmJ Offline
                    jsulm
                    Lifetime Qt Champion
                    wrote on last edited by
                    #8

                    @vidyul said in How to Use Multithreading:

                    Can I have more than 1 worker class inherited from Q Thread?

                    Sure, each of the worker runs then in its own thread.
                    "And How can I achieve that?" - in the same way you create one worker.

                    https://forum.qt.io/topic/113070/qt-code-of-conduct

                    V 1 Reply Last reply
                    1
                    • jsulmJ jsulm

                      @vidyul said in How to Use Multithreading:

                      Can I have more than 1 worker class inherited from Q Thread?

                      Sure, each of the worker runs then in its own thread.
                      "And How can I achieve that?" - in the same way you create one worker.

                      V Offline
                      V Offline
                      vidyul
                      wrote on last edited by vidyul
                      #9

                      @jsulm
                      @J-Hilk
                      Thank you for that info. I am currently facing an issue with the QThread you suggested.
                      After I finish with my task I am clicking a button and then going back to login page, but in the background the qthread is still running and printing the output. How should I end that thread when pressed the stop button and again use it when I press the button to start the process.

                      J.HilkJ 1 Reply Last reply
                      0
                      • V vidyul

                        @jsulm
                        @J-Hilk
                        Thank you for that info. I am currently facing an issue with the QThread you suggested.
                        After I finish with my task I am clicking a button and then going back to login page, but in the background the qthread is still running and printing the output. How should I end that thread when pressed the stop button and again use it when I press the button to start the process.

                        J.HilkJ Offline
                        J.HilkJ Offline
                        J.Hilk
                        Moderators
                        wrote on last edited by
                        #10

                        @vidyul usually you call quit() on the thread. Doesn't necessarily work, depends on what you're doing inside the thread. If there's no event loop running, but something like an infinite while loop. You'll have to quit that first.


                        Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                        Q: What's that?
                        A: It's blue light.
                        Q: What does it do?
                        A: It turns blue.

                        V 1 Reply Last reply
                        0
                        • J.HilkJ J.Hilk

                          @vidyul usually you call quit() on the thread. Doesn't necessarily work, depends on what you're doing inside the thread. If there's no event loop running, but something like an infinite while loop. You'll have to quit that first.

                          V Offline
                          V Offline
                          vidyul
                          wrote on last edited by
                          #11

                          @J-Hilk Yes, so in the def run there is a while True running. Will I have to pass the button(s) as an object when I am creating an instance of the DataThread class?

                          Or I need to do something else?

                          J.HilkJ 1 Reply Last reply
                          0
                          • V vidyul

                            @J-Hilk Yes, so in the def run there is a while True running. Will I have to pass the button(s) as an object when I am creating an instance of the DataThread class?

                            Or I need to do something else?

                            J.HilkJ Offline
                            J.HilkJ Offline
                            J.Hilk
                            Moderators
                            wrote on last edited by
                            #12

                            @vidyul I'm not an expert in Python, but I assume there are equivalents to Atomics and or mutex? You need to check that variable every so often inside the loop and exit the loop when the condition is set.

                            Let me ask the AI to whip up an example.


                            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                            Q: What's that?
                            A: It's blue light.
                            Q: What does it do?
                            A: It turns blue.

                            J.HilkJ V 2 Replies Last reply
                            0
                            • J.HilkJ J.Hilk

                              @vidyul I'm not an expert in Python, but I assume there are equivalents to Atomics and or mutex? You need to check that variable every so often inside the loop and exit the loop when the condition is set.

                              Let me ask the AI to whip up an example.

                              J.HilkJ Offline
                              J.HilkJ Offline
                              J.Hilk
                              Moderators
                              wrote on last edited by
                              #13

                              @J-Hilk here you go:

                              import sys
                              import time
                              from PyQt5.QtCore import Qt, QThread, QTimer, QObject, QMutex, pyqtSignal
                              from PyQt5.QtWidgets import QApplication, QLabel, QMainWindow, QPushButton, QVBoxLayout, QWidget
                              
                              class Worker(QObject):
                                  finished = pyqtSignal()
                              
                                  def __init__(self, mutex):
                                      super().__init__()
                                      self.mutex = mutex
                                      self.stop_flag = False
                              
                                  def run_long_task(self):
                                      while not self.stop_flag:
                                          # Simulate some work
                                          time.sleep(1)
                                          print("Worker thread: Doing some work...")
                              
                                      self.finished.emit()
                              
                              class Window(QMainWindow):
                                  def __init__(self):
                                      super().__init__()
                                      self.clicksCount = 0
                                      self.setup_ui()
                              
                                  def setup_ui(self):
                                      self.setWindowTitle("Thread Example")
                                      self.resize(300, 150)
                                      self.centralWidget = QWidget()
                                      self.setCentralWidget(self.centralWidget)
                              
                                      # Create widgets
                                      self.clicksLabel = QLabel("Counting: 0 clicks", self)
                                      self.clicksLabel.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
                                      self.countBtn = QPushButton("Click me!", self)
                                      self.countBtn.clicked.connect(self.count_clicks)
                                      self.longRunningBtn = QPushButton("Long-Running Task!", self)
                                      self.longRunningBtn.clicked.connect(self.run_long_task)
                              
                                      # Set layout
                                      layout = QVBoxLayout()
                                      layout.addWidget(self.clicksLabel)
                                      layout.addWidget(self.countBtn)
                                      layout.addStretch()
                                      layout.addWidget(self.longRunningBtn)
                                      self.centralWidget.setLayout(layout)
                              
                                  def count_clicks(self):
                                      self.clicksCount += 1
                                      self.clicksLabel.setText(f"Counting: {self.clicksCount} clicks")
                              
                                  def run_long_task(self):
                                      mutex = QMutex()
                                      worker = Worker(mutex)
                              
                                      def stop_worker():
                                          with mutex:
                                              worker.stop_flag = True
                              
                                      # Connect the worker's finished signal to stop the worker
                                      worker.finished.connect(stop_worker)
                              
                                      # Start the worker thread
                                      thread = QThread()
                                      worker.moveToThread(thread)
                                      thread.started.connect(worker.run_long_task)
                                      thread.start()
                              
                              if __name__ == "__main__":
                                  app = QApplication(sys.argv)
                                  win = Window()
                                  win.show()
                                  sys.exit(app.exec_())
                              
                              

                              Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                              Q: What's that?
                              A: It's blue light.
                              Q: What does it do?
                              A: It turns blue.

                              V 1 Reply Last reply
                              0
                              • J.HilkJ J.Hilk

                                @vidyul I'm not an expert in Python, but I assume there are equivalents to Atomics and or mutex? You need to check that variable every so often inside the loop and exit the loop when the condition is set.

                                Let me ask the AI to whip up an example.

                                V Offline
                                V Offline
                                vidyul
                                wrote on last edited by
                                #14
                                This post is deleted!
                                1 Reply Last reply
                                0
                                • J.HilkJ J.Hilk

                                  @J-Hilk here you go:

                                  import sys
                                  import time
                                  from PyQt5.QtCore import Qt, QThread, QTimer, QObject, QMutex, pyqtSignal
                                  from PyQt5.QtWidgets import QApplication, QLabel, QMainWindow, QPushButton, QVBoxLayout, QWidget
                                  
                                  class Worker(QObject):
                                      finished = pyqtSignal()
                                  
                                      def __init__(self, mutex):
                                          super().__init__()
                                          self.mutex = mutex
                                          self.stop_flag = False
                                  
                                      def run_long_task(self):
                                          while not self.stop_flag:
                                              # Simulate some work
                                              time.sleep(1)
                                              print("Worker thread: Doing some work...")
                                  
                                          self.finished.emit()
                                  
                                  class Window(QMainWindow):
                                      def __init__(self):
                                          super().__init__()
                                          self.clicksCount = 0
                                          self.setup_ui()
                                  
                                      def setup_ui(self):
                                          self.setWindowTitle("Thread Example")
                                          self.resize(300, 150)
                                          self.centralWidget = QWidget()
                                          self.setCentralWidget(self.centralWidget)
                                  
                                          # Create widgets
                                          self.clicksLabel = QLabel("Counting: 0 clicks", self)
                                          self.clicksLabel.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
                                          self.countBtn = QPushButton("Click me!", self)
                                          self.countBtn.clicked.connect(self.count_clicks)
                                          self.longRunningBtn = QPushButton("Long-Running Task!", self)
                                          self.longRunningBtn.clicked.connect(self.run_long_task)
                                  
                                          # Set layout
                                          layout = QVBoxLayout()
                                          layout.addWidget(self.clicksLabel)
                                          layout.addWidget(self.countBtn)
                                          layout.addStretch()
                                          layout.addWidget(self.longRunningBtn)
                                          self.centralWidget.setLayout(layout)
                                  
                                      def count_clicks(self):
                                          self.clicksCount += 1
                                          self.clicksLabel.setText(f"Counting: {self.clicksCount} clicks")
                                  
                                      def run_long_task(self):
                                          mutex = QMutex()
                                          worker = Worker(mutex)
                                  
                                          def stop_worker():
                                              with mutex:
                                                  worker.stop_flag = True
                                  
                                          # Connect the worker's finished signal to stop the worker
                                          worker.finished.connect(stop_worker)
                                  
                                          # Start the worker thread
                                          thread = QThread()
                                          worker.moveToThread(thread)
                                          thread.started.connect(worker.run_long_task)
                                          thread.start()
                                  
                                  if __name__ == "__main__":
                                      app = QApplication(sys.argv)
                                      win = Window()
                                      win.show()
                                      sys.exit(app.exec_())
                                  
                                  
                                  V Offline
                                  V Offline
                                  vidyul
                                  wrote on last edited by vidyul
                                  #15

                                  @J-Hilk
                                  So the current main.py file is:
                                  sample.png
                                  Now I want to know where should I implement this part:
                                  def run_long_task(self):
                                  mutex = QMutex()
                                  worker = Worker(mutex)

                                      def stop_worker():
                                          with mutex:
                                              worker.stop_flag = True
                                  
                                      # Connect the worker's finished signal to stop the worker
                                      worker.finished.connect(stop_worker)
                                  

                                  because I tried but it was not working. It prompt to force close the UI.
                                  @J-Hilk

                                  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