title: a serial port thread in pyQT5
body: <p>The following is my code. I am trying to create a serial port thread in my pyQt5 GUI. I checked many examples. This is very helpful one <a href="https://stackoverflow.com/questions/6783194/background-thread-with-qthread-in-pyqt/6789205#6789205">Background thread with QThread in PyQt</a></p>
  
  <p>I think I made a successful connection but I am confused about the signature.</p>
  
  <p>SelectedItem is the selected port. The GUI is still freezing because of while loop.</p>
  
  <p>I need some help. Thanks!</p>
  
  <pre><code>#!/usr/bin/env python3
  #-*- coding:utf-8 -*-
  # vim:fileencoding=utf-8
  
  from PyQt5.QtCore import *
  from PyQt5.QtGui import *
  from PyQt5.QtWidgets import *
  from TTP_Monitor_GUI import Ui_MainWindow
  import serial
  import serial.tools.list_ports
  import binascii
  import glob
  
  class SerialPort(QObject):
      def __init__(self, parent = None):
          super(SerialPort, self).__init__(parent)
  
  
      # Explicit signal
      newParams = pyqtSignal(str)
  
      @pyqtSlot(str)
      def ReadSerialPort(self, port):
          #initialization and open the port
          with serial.Serial(port, 115200, timeout=1) as ser:
  
              print ("Starting up")
              while True:
  
                  readOut = 0   #chars waiting from laser range finder
  
                  #readOut = ser.readline().decode('ascii')
                  readOut = ser.read(268)                         # Reads # Bytes
                  r = binascii.hexlify(readOut).decode('ascii')
                  print(r)
                 self.newParams.emit(r)
                 #ser.flush() #flush the buffer
  
          if ser.isOpen() == False:
              print("Serial Port is Close")
  
  class Main(QMainWindow):
      # Explicit Signal
      #ser = pyqtSignal(str)
  
      def __init__(self, parent=None):
          super(QMainWindow, self).__init__(parent)
          #QMainWindow.__init__(self, parent)
          self.ui = Ui_MainWindow()
          self.ui.setupUi(self)
          self.ui.btnRefresh.clicked.connect(self.Refresh)
          self.ui.btnConnect.clicked.connect(self.Connect)
  
          self.ListFunction(self.SerialPorts())
  
      # Implicit Slot
      def Connect(self):
          Items = self.ui.listMain.selectedItems()
          if len(Items) != 1:
              msg = QMessageBox()
              msg.setIcon(QMessageBox.Critical)
              msg.setWindowTitle("BE CAREFULL!")
              msg.setText("SELECT ONLY 1 ITEM!...")
              msg.exec_()
          else:
              SelectedItem = Items[0].text()
              SelectedItem = SelectedItem.split(" ")[0]
              if sys.platform.startswith('win') and SelectedItem[:3] != 'COM':
                  msg = QMessageBox()
                  msg.setIcon(QMessageBox.Critical)
                  msg.setWindowTitle("BE CAREFULL!")
                  msg.setText("THERE IS A MISTAKE!...")
                  msg.exec_()
                  return
  
          # Read Selected Serial Port
          self.serialThread = QThread()
          self.ser = SerialPort()
          self.ser.moveToThread(self.serialThread)
          self.ser.newParams.connect(self.serialThread.quit)
          #self.serialThread.started.connect(self.ser.ReadSerialPort(SelectedItem))
          self.serialThread.started.connect(lambda port=SelectedItem: self.ser.ReadSerialPort(port))
          self.serialThread.start()
  
  
      def Refresh(self):
          """ Refresh List Widget """
          self.ui.listMain.clear()
          if self.ui.radioSerialPorts.isChecked() == True:
              self.ListFunction(self.SerialPorts())
          elif self.ui.radioTCP.isChecked() == True:
              pass
  
      def ListFunction(self, items):
          """ Lists items into List Widget """
          if type(items) == list and type(items[0]) == str:
              #qApp.processEvents() # See Changes on GUI
              self.ui.listMain.addItems(items)
          else:
              msg = QMessageBox()
              msg.setIcon(QMessageBox.Critical)
              msg.setWindowTitle("BE CAREFULL!")
              msg.setText("ITEMS ARE WRONG!...")
              msg.exec_()
  
      def SerialPorts(self):
          """ Lists serial port names """
          device = []
          description = []
          result = []
          for port in serial.tools.list_ports.comports():
              device.append(port.device)
              description.append(port.description)
              result.append(port.device + ' - ' + port.description)
          return result
  
  if __name__ == "__main__":
      import sys
      app = QApplication(sys.argv)
      myapp = Main()
      myapp.show()
      sys.exit(app.exec_())
  </code></pre>