pyQT5中的串口线程

时间:2018-03-27 17:25:46

标签: python-3.x pyqt5 pyserial qthread

以下是我的代码。我试图在我的pyQt5 GUI中创建一个串口线程。我查了很多例子。这对Background thread with QThread in PyQt

非常有帮助

我认为我成功建立了连接,但我对签名感到困惑。

SelectedItem是选定的端口。由于while循环,GUI仍然处于冻结状态。

我需要一些帮助。谢谢!

#!/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_())

1 个答案:

答案 0 :(得分:0)

在while循环内的线程函数time.sleep(1)上提供延迟函数ReadSerialPort(self, port),在函数self.newParams.emit(r)之后。

pyqt UI没有足够的时间执行。因此提供延迟。它会起作用。