2

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 Background thread with QThread in PyQt

I think I made a successful connection but I am confused about the signature.

SelectedItem is the selected port. The GUI is still freezing because of while loop.

I need some help. Thanks!

#!/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_())
B. Sunan
  • 21
  • 1
  • 6

1 Answers1

0

provide delay function time.sleep(1) at thread function ReadSerialPort(self, port) inside the while loop äfter the function self.newParams.emit(r).

pyqt UI does not gets sufficient time to execute. so provide delay. it will work.

Sociopath
  • 13,068
  • 19
  • 47
  • 75