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. PyQt5 display variable from Thread to LCD
Forum Updated to NodeBB v4.3 + New Features

PyQt5 display variable from Thread to LCD

Scheduled Pinned Locked Moved Unsolved General and Desktop
12 Posts 4 Posters 4.9k Views 2 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.
  • SGaistS Offline
    SGaistS Offline
    SGaist
    Lifetime Qt Champion
    wrote on last edited by
    #2

    Hi and welcome to devnet,

    You should emit a signal from your thread that you’ll connect to a slot that will update the LCD and the variable.

    And also add a slot to your thread that you’ll connect to your checkbox.

    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
    2
    • W Offline
      W Offline
      webgiorgio
      wrote on last edited by
      #3

      Hi, thanks for your hint.
      I understand the logic you pointed out, but I know so little PyQt that I don't know how to implement what you suggested.

      I managed to solve half of the problem. The signal for the value of "i" works, for the checkbox it only works with the method I commented out. When I insert it in the "run" method, I get the error: "TypeError: run() missing 1 required positional argument: 'b'". I don't know how to address it

      #!/usr/bin/env python3
      # -*- coding: utf-8 -*-
      """
      Created on Sat Aug 11 15:48:57 2018
      
      """
      
      import sys
      from PyQt5.QtCore import Qt
      from PyQt5.QtWidgets import (QWidget, QLCDNumber, QSlider, QProgressBar,
          QVBoxLayout, QApplication, QCheckBox )
      from PyQt5.QtCore import QThread, pyqtSignal
      
      import time
      
                 
      
      class WorkerThread(QThread):
          signal_i=pyqtSignal( int, name='Signal_i') ### 1) declare the signal
          
          def __init__(self, parent=None):
              QThread.__init__(self)
              #super(WorkerThread, self).__init__(parent)
         
          def run(self, b):
              if b == 0:
                  print ("non checked")
              else:
                  print("checked")
              
              x = 10
              for i in range(x):
                 time.sleep(1)
                 #print(i) 
                 self.signal_i.emit(i)  ### 2) emitt the signal
              
              
      class Example(QWidget):
          def __init__(self):
              super().__init__()
              self.initUI()
              self.wt=WorkerThread() # This is the thread object
              self.wt.start()
              # Connect the signal from the thread to the finished method
              self.wt.signal_i.connect(self.slot_method)  ### 3) connect to the slot
              
          def initUI(self):
              cb  = QCheckBox("enable countdown")
              self.lcd = QLCDNumber(self)
              pro = QProgressBar(self)
              sld = QSlider(Qt.Horizontal, self)
      
              vbox = QVBoxLayout()
              vbox.addWidget(cb)
              vbox.addWidget(self.lcd)
              vbox.addWidget(pro)
              vbox.addWidget(sld)
              self.setLayout(vbox)
         
              self.setGeometry(300, 300, 250, 150)
              self.setWindowTitle('Signal and slot')
              self.show()
              
              sld.valueChanged.connect(pro.setValue)#link the slider to the progress bar
              #cb.stateChanged.connect(self.buttonchange)
              cb.stateChanged.connect(WorkerThread.run)
              
          def slot_method(self, i):   ### 4) this is the slot that receive the signal
              #print("i:",+i)
              self.lcd.display(i)
              
      #    def buttonchange(self, b):
      #        if b == 0:
      #            print ("non checked")
      #        else:
      #            print("checked")
      
      if __name__ == '__main__':
          app = QApplication(sys.argv)
          ex = Example()
          sys.exit(app.exec_())
      
      
      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #4

        Why are you trying to connect the checkbox to the run method ? That's not the goal of that method at all.

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

        W 1 Reply Last reply
        0
        • SGaistS SGaist

          Why are you trying to connect the checkbox to the run method ? That's not the goal of that method at all.

          W Offline
          W Offline
          webgiorgio
          wrote on last edited by
          #5

          @SGaist I want to use that check box to exit the while loop I will have in the Thread (reading data from the serial port, and sending it to the lcd).
          Otherwise when I close the GUI the Thread keeps running.

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

            You can use QThread:: requestInterruption and in your run method isInterruptionRequested.

            But the check box is a wrong GUI idea, you should rather use a normal button.

            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
            • W Offline
              W Offline
              webgiorgio
              wrote on last edited by webgiorgio
              #7
              This post is deleted!
              1 Reply Last reply
              0
              • W Offline
                W Offline
                webgiorgio
                wrote on last edited by webgiorgio
                #8

                The idea of the checkbox is to ebnable/disable the serial data read when the checkbox is selected/unselected.
                It works with the method cbchange. Is this what you meant?

                If I connect the interruption to the pushbutton, the gui hangs at boot

                btn.clicked.connect(self.wt.requestInterruption()) #THIS HANGS
                
                #!/usr/bin/env python3
                # -*- coding: utf-8 -*-
                """
                Created on Sat Aug 11 15:48:57 2018
                
                @author: gio
                """
                
                
                import sys
                from PyQt5.QtCore import Qt
                from PyQt5.QtWidgets import (QWidget, QLCDNumber, QSlider, QProgressBar,
                    QVBoxLayout, QApplication, QCheckBox, QPushButton)
                from PyQt5.QtCore import QThread, pyqtSignal
                
                import time
                
                           
                
                class WorkerThread(QThread):
                    mysignal_i=pyqtSignal( int, name='Signal_i') ### 1) declare the signal
                    
                    def __init__(self, parent=None):
                        QThread.__init__(self)
                        #super(WorkerThread, self).__init__(parent)
                   
                    def run(self):
                        x = 10
                        for i in range(x):
                           time.sleep(1)
                           print(i) 
                           self.mysignal_i.emit(i)  ### 2) emitt the signal
                           if self.isInterruptionRequested():
                               print ("exit loop")
                               break
                           
                        
                        
                class Example(QWidget):
                    def __init__(self):
                        super().__init__()
                        self.initUI()
                        self.wt=WorkerThread() # This is the thread object
                        #self.wt.start()
                        # Connect the signal from the thread to the slot_method
                        self.wt.mysignal_i.connect(self.slot_method)  ### 3) connect to the slot
                        
                    def initUI(self):
                        cb  = QCheckBox("enable countdown")
                        cb.setChecked(False)
                        self.lcd = QLCDNumber(self)
                        pro = QProgressBar(self)
                        sld = QSlider(Qt.Horizontal, self)
                        btn = QPushButton(self)
                        btn.setText('stop thread')
                
                        vbox = QVBoxLayout()
                        vbox.addWidget(cb)
                        vbox.addWidget(btn)
                        vbox.addWidget(self.lcd)
                        vbox.addWidget(pro)
                        vbox.addWidget(sld)
                        self.setLayout(vbox)
                
                
                        self.setGeometry(300, 300, 300, 300)
                        self.setWindowTitle('Signal and slot')
                        self.show()
                        
                        sld.valueChanged.connect(pro.setValue)#link the slider to the progress bar
                        cb.stateChanged.connect(self.cbchange)
                        #cb.stateChanged.connect(WorkerThread.run)
                        
                        #btn.clicked.connect(self.wt.requestInterruption()) #THIS HANGS
                        
                    def slot_method(self, i):   ### 4) this is the slot that receive the signal
                        #print("i:",+i)
                        self.lcd.display(i)
                        
                    def cbchange(self, b):
                        if b == 0:
                            print ("non checked")
                            self.wt.requestInterruption()
                        else:
                            print("checked")
                            self.wt.start()
                
                if __name__ == '__main__':
                    app = QApplication(sys.argv)
                    ex = Example()
                    sys.exit(app.exec_())
                
                
                JonBJ 1 Reply Last reply
                0
                • mrjjM Offline
                  mrjjM Offline
                  mrjj
                  Lifetime Qt Champion
                  wrote on last edited by
                  #9

                  Hi
                  Does break in python do the same as return in c++ ?

                  void long_task() {
                       forever {
                          if ( QThread::currentThread()->isInterruptionRequested() ) {
                              return;
                          }
                      }
                  }
                  

                  If its break like in c++ , you only ask it to skip for loop but not bail out of run()
                  (i think/assume)

                  JonBJ 1 Reply Last reply
                  0
                  • mrjjM mrjj

                    Hi
                    Does break in python do the same as return in c++ ?

                    void long_task() {
                         forever {
                            if ( QThread::currentThread()->isInterruptionRequested() ) {
                                return;
                            }
                        }
                    }
                    

                    If its break like in c++ , you only ask it to skip for loop but not bail out of run()
                    (i think/assume)

                    JonBJ Online
                    JonBJ Online
                    JonB
                    wrote on last edited by
                    #10

                    @mrjj
                    Python break == C++ break
                    Python return == C++ return
                    :)

                    mrjjM 1 Reply Last reply
                    2
                    • JonBJ JonB

                      @mrjj
                      Python break == C++ break
                      Python return == C++ return
                      :)

                      mrjjM Offline
                      mrjjM Offline
                      mrjj
                      Lifetime Qt Champion
                      wrote on last edited by
                      #11

                      @JonB
                      Thanks so exactly the same.
                      so i guess it hangs as he only exit the for loop and run
                      repeats a moment later.

                      1 Reply Last reply
                      0
                      • W webgiorgio

                        The idea of the checkbox is to ebnable/disable the serial data read when the checkbox is selected/unselected.
                        It works with the method cbchange. Is this what you meant?

                        If I connect the interruption to the pushbutton, the gui hangs at boot

                        btn.clicked.connect(self.wt.requestInterruption()) #THIS HANGS
                        
                        #!/usr/bin/env python3
                        # -*- coding: utf-8 -*-
                        """
                        Created on Sat Aug 11 15:48:57 2018
                        
                        @author: gio
                        """
                        
                        
                        import sys
                        from PyQt5.QtCore import Qt
                        from PyQt5.QtWidgets import (QWidget, QLCDNumber, QSlider, QProgressBar,
                            QVBoxLayout, QApplication, QCheckBox, QPushButton)
                        from PyQt5.QtCore import QThread, pyqtSignal
                        
                        import time
                        
                                   
                        
                        class WorkerThread(QThread):
                            mysignal_i=pyqtSignal( int, name='Signal_i') ### 1) declare the signal
                            
                            def __init__(self, parent=None):
                                QThread.__init__(self)
                                #super(WorkerThread, self).__init__(parent)
                           
                            def run(self):
                                x = 10
                                for i in range(x):
                                   time.sleep(1)
                                   print(i) 
                                   self.mysignal_i.emit(i)  ### 2) emitt the signal
                                   if self.isInterruptionRequested():
                                       print ("exit loop")
                                       break
                                   
                                
                                
                        class Example(QWidget):
                            def __init__(self):
                                super().__init__()
                                self.initUI()
                                self.wt=WorkerThread() # This is the thread object
                                #self.wt.start()
                                # Connect the signal from the thread to the slot_method
                                self.wt.mysignal_i.connect(self.slot_method)  ### 3) connect to the slot
                                
                            def initUI(self):
                                cb  = QCheckBox("enable countdown")
                                cb.setChecked(False)
                                self.lcd = QLCDNumber(self)
                                pro = QProgressBar(self)
                                sld = QSlider(Qt.Horizontal, self)
                                btn = QPushButton(self)
                                btn.setText('stop thread')
                        
                                vbox = QVBoxLayout()
                                vbox.addWidget(cb)
                                vbox.addWidget(btn)
                                vbox.addWidget(self.lcd)
                                vbox.addWidget(pro)
                                vbox.addWidget(sld)
                                self.setLayout(vbox)
                        
                        
                                self.setGeometry(300, 300, 300, 300)
                                self.setWindowTitle('Signal and slot')
                                self.show()
                                
                                sld.valueChanged.connect(pro.setValue)#link the slider to the progress bar
                                cb.stateChanged.connect(self.cbchange)
                                #cb.stateChanged.connect(WorkerThread.run)
                                
                                #btn.clicked.connect(self.wt.requestInterruption()) #THIS HANGS
                                
                            def slot_method(self, i):   ### 4) this is the slot that receive the signal
                                #print("i:",+i)
                                self.lcd.display(i)
                                
                            def cbchange(self, b):
                                if b == 0:
                                    print ("non checked")
                                    self.wt.requestInterruption()
                                else:
                                    print("checked")
                                    self.wt.start()
                        
                        if __name__ == '__main__':
                            app = QApplication(sys.argv)
                            ex = Example()
                            sys.exit(app.exec_())
                        
                        
                        JonBJ Online
                        JonBJ Online
                        JonB
                        wrote on last edited by JonB
                        #12

                        @webgiorgio

                        btn.clicked.connect(self.wt.requestInterruption()) #THIS HANGS

                        You're misunderstanding how you're intended to use connect in PyQt. It's the same principle as in C++, just different syntax. The point is, you must connect to the function ("pointer"), you must not call the function in the argument to connect.

                        So all your PyQt connects need to look like:

                        btn.clicked.connect(self.wt.requestInterruption)
                        

                        Note that requestInterruption does not have a () at the end of it! Do you follow the vital difference? It's also the same principle as why you have to write btn.clicked.connect and not btn.clicked().connect.

                        1 Reply Last reply
                        3

                        • Login

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