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. readyRead signal not activating while using QSerialProt
Forum Update on Monday, May 27th 2025

readyRead signal not activating while using QSerialProt

Scheduled Pinned Locked Moved Solved Qt for Python
5 Posts 3 Posters 224 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.
  • A Offline
    A Offline
    Adar70
    wrote on last edited by
    #1

    Hello. I have this program here:

    import sys
    from time import sleep
    
    from PySide6 import QtSerialPort as qts
    from PySide6 import QtCore as qtc
    
    
    class Serial_Port():
        def __init__(self):
            self.port = qts.QSerialPort()
            self.port.setBaudRate(qts.QSerialPort.Baud38400)
            
            self.port.readyRead.connect(self.on_receive)
            self.port.errorOccurred.connect(self.on_error)
    
            qtc.QTimer.singleShot(0, self.program)
    
    
        def program(self):
            print(self.con_discon())
            order = [0x86, 0x01]
            for o in order:
                self.send(o.to_bytes())
                sleep(0.001)
            print("fin")
    
        
        def con_discon(self):
            if self.port.isOpen(): 
                self.port.close() 
                return False
            else: 
                for port in qts.QSerialPortInfo.availablePorts():
                    if port.manufacturer() == 'STMicroelectronics' and port.serialNumber() == '0668FF505271754867083433':
                        self.port.setPort(port)
                        break
                return self.port.open(qtc.QIODeviceBase.ReadWrite)
    
    
        def send(self, data):
            print("send: ", data)
            self.port.write(data)
        
    
        def on_receive(self):
            print('!')
            print("message: ", self.port.read(2))
    
    
        def on_error(self, error):
            print("Serial port error:")
            print(error.name)
            exit()
    
    
    def main():
        if not qtc.QCoreApplication.instance(): 
            app = qtc.QCoreApplication(sys.argv) 
        else:
            app = qtc.QCoreApplication.instance() 
    
        Serial_Port()
    
        app.exec()
    
    
    if __name__ == '__main__':
        main()
    

    It's supposed to send 0x86 and then 0x01 through serial port and get an answer from a device. I know the device is working correctly, because the answer is showing up with Termite and, interestingly, when I run this program without an event loop, which looks like this:

    import sys
    from time import sleep
    
    from PySide6 import QtSerialPort as qts
    from PySide6 import QtCore as qtc
    
    
    class Serial_Port():
        def __init__(self):
            self.port = qts.QSerialPort()
            self.port.setBaudRate(qts.QSerialPort.Baud38400)
            
            self.port.readyRead.connect(self.on_receive)
            self.port.errorOccurred.connect(self.on_error)
    
    
        def program(self):
            print(self.con_discon())
            order = [0x86, 0x01]
            for o in order:
                self.send(o.to_bytes())
                sleep(0.001)
            self.port.waitForReadyRead()
            print("fin")
    
        
        def con_discon(self):
            if self.port.isOpen(): 
                self.port.close() 
                return False
            else: 
                for port in qts.QSerialPortInfo.availablePorts():
                    if port.manufacturer() == 'STMicroelectronics' and port.serialNumber() == '0668FF505271754867083433':
                        self.port.setPort(port)
                        break
                return self.port.open(qtc.QIODeviceBase.ReadWrite)
    
    
        def send(self, data):
            print("send: ", data)
            self.port.write(data)
        
    
        def on_receive(self):
            print('!')
            print("message: ", self.port.read(2))
    
    
        def on_error(self, error):
            print("Serial port error:")
            print(error.name)
            exit()
    
    
    def main():
        sp = Serial_Port()
        sp.program()
    
    
    if __name__ == '__main__':
        main()
    

    I don't know why it doesn't work nor why only without the event loop. With the event loop, after sending the data, it just does nothing. Please help.

    JonBJ 2 Replies Last reply
    0
    • A Adar70

      Hello. I have this program here:

      import sys
      from time import sleep
      
      from PySide6 import QtSerialPort as qts
      from PySide6 import QtCore as qtc
      
      
      class Serial_Port():
          def __init__(self):
              self.port = qts.QSerialPort()
              self.port.setBaudRate(qts.QSerialPort.Baud38400)
              
              self.port.readyRead.connect(self.on_receive)
              self.port.errorOccurred.connect(self.on_error)
      
              qtc.QTimer.singleShot(0, self.program)
      
      
          def program(self):
              print(self.con_discon())
              order = [0x86, 0x01]
              for o in order:
                  self.send(o.to_bytes())
                  sleep(0.001)
              print("fin")
      
          
          def con_discon(self):
              if self.port.isOpen(): 
                  self.port.close() 
                  return False
              else: 
                  for port in qts.QSerialPortInfo.availablePorts():
                      if port.manufacturer() == 'STMicroelectronics' and port.serialNumber() == '0668FF505271754867083433':
                          self.port.setPort(port)
                          break
                  return self.port.open(qtc.QIODeviceBase.ReadWrite)
      
      
          def send(self, data):
              print("send: ", data)
              self.port.write(data)
          
      
          def on_receive(self):
              print('!')
              print("message: ", self.port.read(2))
      
      
          def on_error(self, error):
              print("Serial port error:")
              print(error.name)
              exit()
      
      
      def main():
          if not qtc.QCoreApplication.instance(): 
              app = qtc.QCoreApplication(sys.argv) 
          else:
              app = qtc.QCoreApplication.instance() 
      
          Serial_Port()
      
          app.exec()
      
      
      if __name__ == '__main__':
          main()
      

      It's supposed to send 0x86 and then 0x01 through serial port and get an answer from a device. I know the device is working correctly, because the answer is showing up with Termite and, interestingly, when I run this program without an event loop, which looks like this:

      import sys
      from time import sleep
      
      from PySide6 import QtSerialPort as qts
      from PySide6 import QtCore as qtc
      
      
      class Serial_Port():
          def __init__(self):
              self.port = qts.QSerialPort()
              self.port.setBaudRate(qts.QSerialPort.Baud38400)
              
              self.port.readyRead.connect(self.on_receive)
              self.port.errorOccurred.connect(self.on_error)
      
      
          def program(self):
              print(self.con_discon())
              order = [0x86, 0x01]
              for o in order:
                  self.send(o.to_bytes())
                  sleep(0.001)
              self.port.waitForReadyRead()
              print("fin")
      
          
          def con_discon(self):
              if self.port.isOpen(): 
                  self.port.close() 
                  return False
              else: 
                  for port in qts.QSerialPortInfo.availablePorts():
                      if port.manufacturer() == 'STMicroelectronics' and port.serialNumber() == '0668FF505271754867083433':
                          self.port.setPort(port)
                          break
                  return self.port.open(qtc.QIODeviceBase.ReadWrite)
      
      
          def send(self, data):
              print("send: ", data)
              self.port.write(data)
          
      
          def on_receive(self):
              print('!')
              print("message: ", self.port.read(2))
      
      
          def on_error(self, error):
              print("Serial port error:")
              print(error.name)
              exit()
      
      
      def main():
          sp = Serial_Port()
          sp.program()
      
      
      if __name__ == '__main__':
          main()
      

      I don't know why it doesn't work nor why only without the event loop. With the event loop, after sending the data, it just does nothing. Please help.

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #3

      @Adar70
      Maybe you are doing the above (mostly) in your first code, I looked initially at your second.

      Meanwhile, I am worried about your Python lifetime of the instance you create in first code via plain Serial_Port() call. You do not assign return result to any variable. If I am not mistaken, won't the created Serial_Port instance be destroyed immediately after return from Serial_Port.__init__()? Not certain whether the qtc.QTimer.singleShot(0, self.program) will keep it alive. Even if it does, it may die before the reply bytes are received, at least with no waitFor...(). Verify if that is the case, do something to keep the Serial_Port instance around?

      A 1 Reply Last reply
      2
      • A Adar70

        Hello. I have this program here:

        import sys
        from time import sleep
        
        from PySide6 import QtSerialPort as qts
        from PySide6 import QtCore as qtc
        
        
        class Serial_Port():
            def __init__(self):
                self.port = qts.QSerialPort()
                self.port.setBaudRate(qts.QSerialPort.Baud38400)
                
                self.port.readyRead.connect(self.on_receive)
                self.port.errorOccurred.connect(self.on_error)
        
                qtc.QTimer.singleShot(0, self.program)
        
        
            def program(self):
                print(self.con_discon())
                order = [0x86, 0x01]
                for o in order:
                    self.send(o.to_bytes())
                    sleep(0.001)
                print("fin")
        
            
            def con_discon(self):
                if self.port.isOpen(): 
                    self.port.close() 
                    return False
                else: 
                    for port in qts.QSerialPortInfo.availablePorts():
                        if port.manufacturer() == 'STMicroelectronics' and port.serialNumber() == '0668FF505271754867083433':
                            self.port.setPort(port)
                            break
                    return self.port.open(qtc.QIODeviceBase.ReadWrite)
        
        
            def send(self, data):
                print("send: ", data)
                self.port.write(data)
            
        
            def on_receive(self):
                print('!')
                print("message: ", self.port.read(2))
        
        
            def on_error(self, error):
                print("Serial port error:")
                print(error.name)
                exit()
        
        
        def main():
            if not qtc.QCoreApplication.instance(): 
                app = qtc.QCoreApplication(sys.argv) 
            else:
                app = qtc.QCoreApplication.instance() 
        
            Serial_Port()
        
            app.exec()
        
        
        if __name__ == '__main__':
            main()
        

        It's supposed to send 0x86 and then 0x01 through serial port and get an answer from a device. I know the device is working correctly, because the answer is showing up with Termite and, interestingly, when I run this program without an event loop, which looks like this:

        import sys
        from time import sleep
        
        from PySide6 import QtSerialPort as qts
        from PySide6 import QtCore as qtc
        
        
        class Serial_Port():
            def __init__(self):
                self.port = qts.QSerialPort()
                self.port.setBaudRate(qts.QSerialPort.Baud38400)
                
                self.port.readyRead.connect(self.on_receive)
                self.port.errorOccurred.connect(self.on_error)
        
        
            def program(self):
                print(self.con_discon())
                order = [0x86, 0x01]
                for o in order:
                    self.send(o.to_bytes())
                    sleep(0.001)
                self.port.waitForReadyRead()
                print("fin")
        
            
            def con_discon(self):
                if self.port.isOpen(): 
                    self.port.close() 
                    return False
                else: 
                    for port in qts.QSerialPortInfo.availablePorts():
                        if port.manufacturer() == 'STMicroelectronics' and port.serialNumber() == '0668FF505271754867083433':
                            self.port.setPort(port)
                            break
                    return self.port.open(qtc.QIODeviceBase.ReadWrite)
        
        
            def send(self, data):
                print("send: ", data)
                self.port.write(data)
            
        
            def on_receive(self):
                print('!')
                print("message: ", self.port.read(2))
        
        
            def on_error(self, error):
                print("Serial port error:")
                print(error.name)
                exit()
        
        
        def main():
            sp = Serial_Port()
            sp.program()
        
        
        if __name__ == '__main__':
            main()
        

        I don't know why it doesn't work nor why only without the event loop. With the event loop, after sending the data, it just does nothing. Please help.

        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by
        #2

        @Adar70
        Don't do sleep()s. Allow the event loop to run. Don't use both readyRead() signal and waitForReadyRead(). Get rid of the latter. Don't read 2 bytes in case there is only 1. There's a start.

        1 Reply Last reply
        0
        • A Adar70

          Hello. I have this program here:

          import sys
          from time import sleep
          
          from PySide6 import QtSerialPort as qts
          from PySide6 import QtCore as qtc
          
          
          class Serial_Port():
              def __init__(self):
                  self.port = qts.QSerialPort()
                  self.port.setBaudRate(qts.QSerialPort.Baud38400)
                  
                  self.port.readyRead.connect(self.on_receive)
                  self.port.errorOccurred.connect(self.on_error)
          
                  qtc.QTimer.singleShot(0, self.program)
          
          
              def program(self):
                  print(self.con_discon())
                  order = [0x86, 0x01]
                  for o in order:
                      self.send(o.to_bytes())
                      sleep(0.001)
                  print("fin")
          
              
              def con_discon(self):
                  if self.port.isOpen(): 
                      self.port.close() 
                      return False
                  else: 
                      for port in qts.QSerialPortInfo.availablePorts():
                          if port.manufacturer() == 'STMicroelectronics' and port.serialNumber() == '0668FF505271754867083433':
                              self.port.setPort(port)
                              break
                      return self.port.open(qtc.QIODeviceBase.ReadWrite)
          
          
              def send(self, data):
                  print("send: ", data)
                  self.port.write(data)
              
          
              def on_receive(self):
                  print('!')
                  print("message: ", self.port.read(2))
          
          
              def on_error(self, error):
                  print("Serial port error:")
                  print(error.name)
                  exit()
          
          
          def main():
              if not qtc.QCoreApplication.instance(): 
                  app = qtc.QCoreApplication(sys.argv) 
              else:
                  app = qtc.QCoreApplication.instance() 
          
              Serial_Port()
          
              app.exec()
          
          
          if __name__ == '__main__':
              main()
          

          It's supposed to send 0x86 and then 0x01 through serial port and get an answer from a device. I know the device is working correctly, because the answer is showing up with Termite and, interestingly, when I run this program without an event loop, which looks like this:

          import sys
          from time import sleep
          
          from PySide6 import QtSerialPort as qts
          from PySide6 import QtCore as qtc
          
          
          class Serial_Port():
              def __init__(self):
                  self.port = qts.QSerialPort()
                  self.port.setBaudRate(qts.QSerialPort.Baud38400)
                  
                  self.port.readyRead.connect(self.on_receive)
                  self.port.errorOccurred.connect(self.on_error)
          
          
              def program(self):
                  print(self.con_discon())
                  order = [0x86, 0x01]
                  for o in order:
                      self.send(o.to_bytes())
                      sleep(0.001)
                  self.port.waitForReadyRead()
                  print("fin")
          
              
              def con_discon(self):
                  if self.port.isOpen(): 
                      self.port.close() 
                      return False
                  else: 
                      for port in qts.QSerialPortInfo.availablePorts():
                          if port.manufacturer() == 'STMicroelectronics' and port.serialNumber() == '0668FF505271754867083433':
                              self.port.setPort(port)
                              break
                      return self.port.open(qtc.QIODeviceBase.ReadWrite)
          
          
              def send(self, data):
                  print("send: ", data)
                  self.port.write(data)
              
          
              def on_receive(self):
                  print('!')
                  print("message: ", self.port.read(2))
          
          
              def on_error(self, error):
                  print("Serial port error:")
                  print(error.name)
                  exit()
          
          
          def main():
              sp = Serial_Port()
              sp.program()
          
          
          if __name__ == '__main__':
              main()
          

          I don't know why it doesn't work nor why only without the event loop. With the event loop, after sending the data, it just does nothing. Please help.

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by
          #3

          @Adar70
          Maybe you are doing the above (mostly) in your first code, I looked initially at your second.

          Meanwhile, I am worried about your Python lifetime of the instance you create in first code via plain Serial_Port() call. You do not assign return result to any variable. If I am not mistaken, won't the created Serial_Port instance be destroyed immediately after return from Serial_Port.__init__()? Not certain whether the qtc.QTimer.singleShot(0, self.program) will keep it alive. Even if it does, it may die before the reply bytes are received, at least with no waitFor...(). Verify if that is the case, do something to keep the Serial_Port instance around?

          A 1 Reply Last reply
          2
          • JonBJ JonB

            @Adar70
            Maybe you are doing the above (mostly) in your first code, I looked initially at your second.

            Meanwhile, I am worried about your Python lifetime of the instance you create in first code via plain Serial_Port() call. You do not assign return result to any variable. If I am not mistaken, won't the created Serial_Port instance be destroyed immediately after return from Serial_Port.__init__()? Not certain whether the qtc.QTimer.singleShot(0, self.program) will keep it alive. Even if it does, it may die before the reply bytes are received, at least with no waitFor...(). Verify if that is the case, do something to keep the Serial_Port instance around?

            A Offline
            A Offline
            Adar70
            wrote on last edited by
            #4

            @JonB Thanks for the reply. After putting the call to Serial_Port() in a variable like sp = Serial_Port() in the code with event loop it worked. Sadly the amount of times the readyRead signal is emitted is unreliable. Sometimes it's two, sometimes it's three. I don't know how to make it more robust. Could you help with that?

            jsulmJ 1 Reply Last reply
            0
            • A Adar70

              @JonB Thanks for the reply. After putting the call to Serial_Port() in a variable like sp = Serial_Port() in the code with event loop it worked. Sadly the amount of times the readyRead signal is emitted is unreliable. Sometimes it's two, sometimes it's three. I don't know how to make it more robust. Could you help with that?

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

              @Adar70 said in readyRead signal not activating while using QSerialProt:

              I don't know how to make it more robust

              Don't rely on the number of times readyRead is emitted. Instead accumulate the received data until you received all you expect to receive.

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

              1 Reply Last reply
              5
              • A Adar70 has marked this topic as solved on

              • Login

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