PHP前端开发

Python之PyQT多线程串口代码分析

百变鹏仔 3小时前 #Python
文章标签 串口

这篇文章主要介绍了Python之PyQT多线程串口代码分析,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

这篇博客主要记录一下pyqt多线程串口的主要代码分析,文末会有工程的源代码文件
首先,从pycharm启动qtdesigner 



之前给客户做的上位机,保密起见,删减了大部分的框图构件,但不影响本篇串口教程
QtDesigner界面如下: 



忽略 添加数据以及表格数据显示,这里用不到
着重讲一下类的构成
新建一个串口类SerialThread,继承自QtCore.QThread,实现全部的串口收发功能

class SerialThread(QtCore.QThread):    dataReadoutSignal = pyqtSignal(str)    def __init__(self, parent = None, portName = 'COM3', baudrate = 9600, parity = 'N', bytesize = 8, stopbits = 1, timeout = None):        super(SerialThread, self).__init__(parent)        self.m_serialPort = serial.Serial()        self.m_serialPort.port = portName        self.m_serialPort.baudrate = baudrate        self.m_serialPort.parity = parity        self.m_serialPort.bytesize = bytesize        self.m_serialPort.stopbits = stopbits        self.m_serialPort.timeout = timeout        self.OpenScom()    def OpenScom(self):        try:            self.m_serialPort.open()            self.m_serialPort.setRTS(True)            self.m_serialPort.setDTR(True)        except Exception as ex:            print(ex)            return ex    def ScomSendOneData(self,datain):        if isinstance(datain,int):            listTemp = []            listTemp.append(datain)            d = bytes(listTemp)            self.m_serialPort.write(d)        else:            if isinstance(datain,str):                d = datain.encode('utf-8')                self.m_serialPort.write(d)    def ScomGetintData(self):        n = self.m_serialPort.inWaiting()        if n:            data = self.m_serialPort.read(n).hex()            #writefile            print(data)    def ScomGetstrData(self):        if self.m_serialPort.is_open:            n = self.m_serialPort.inWaiting()            if n &gt; 0:                data = self.m_serialPort.read(n).decode('GB2312',errors='ignore')                return data    def run(self):        cnt = 50        while cnt <p>函数功能见名知意,此处不表。这里主要讲一下run函数,run函数实现了一次循环,50到3000步进取5,发送内容是SET0050V到SET3000V,当然,我这样做是业务需求,如果并不需要这个功能,run函数可以写成</p><pre class="brush:php;toolbar:false;">    def run(self):        while true:            time.sleep(2)

界面我们用QtDesigner制作的ui文件通过pyUIC生成py文件 

立即学习“Python免费学习笔记(深入)”;



生成的代码如下(太长,只留前几行)

# -*- coding: utf-8 -*-# Form implementation generated from reading ui file 'CashUpdateUI11v.ui'## Created by: PyQt5 UI code generator 5.6## WARNING! All changes made in this file will be lost!from PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_cash(object):    def setupUi(self, cash):    **    **    **

此时,新建一个类MyWindow,继承QMainWindow和Ui_cash,并在类内部,创建SerialThread成员
总体代码如下:

class MyWindow(QMainWindow,Ui_cash):    def __init__(self):        super(MyWindow,self).__init__()        self.scomList = []        self.threadList = []        self.setupUi(self)        self.actionOpen.triggered.connect(self.openMsg)        self.actionSave.triggered.connect(self.saveMsg)        self.pushButton.clicked.connect(self.ScomAutoFind)        self.addDataButton.clicked.connect(self.getRHandT)        self.tableWidget.setColumnCount(5)        self.tableWidget.setRowCount(1)        self.tableWidget.setHorizontalHeaderLabels(['11', '22', '33', '44', '55'])        self.tableRowCnt = 0        self.tableColumnCnt = 0        self.ThreadComID = 0        self.addDatasignal = pyqtSignal(str)        self.datadict = {'RHldy':0,'Tldy':0,'meaRT':0,'voltport':0}    def getMCUdata(self):        if self.ThreadComID == 0:            self.showMsgbox('请先连接串口')        else:            self.ThreadComID.ScomSendOneData(' 5501AA')            time.sleep(0.1)            strt = self.ThreadComID.ScomGetstrData()            if strt is None:                self.showMsgbox('请将串口线连接到电路板')                return None            print(strt)            self.datadict['voltport'] = strt[4:-3] + '.' + strt[-3:-2]            self.ThreadComID.ScomSendOneData(' 5502AA')            time.sleep(0.1)            strt = self.ThreadComID.ScomGetstrData()            if strt is None:                self.showMsgbox('请将串口线连接到电路板')                return None            print(strt)            self.datadict['meaRT'] = strt[4:-4] + '.' + strt[-4:-2]            return 1    def insertTableNewLine(self):        self.tableWidget.setItem(self.tableRowCnt, 0, QTableWidgetItem(self.datadict['RHldy']))        self.tableWidget.setItem(self.tableRowCnt, 1, QTableWidgetItem(self.datadict['Tldy']))        self.tableWidget.setItem(self.tableRowCnt, 2, QTableWidgetItem(self.datadict['meaRT']))        self.tableWidget.setItem(self.tableRowCnt, 3, QTableWidgetItem(self.datadict['voltport']))        self.tableWidget.setItem(self.tableRowCnt, 4, QTableWidgetItem(str(datetime.date.today())+' '+str(datetime.datetime.today().hour)+':'+str(datetime.datetime.today().minute)))        self.tableRowCnt += 1        self.tableWidget.insertRow(self.tableRowCnt)    def openMsg(self):        file,ok = QFileDialog.getOpenFileName(self,"打开记录表","C:/",".txt")    def getRHandT(self):        if self.ThreadComID == 0:            self.showMsgbox('请先连接串口')        else:            data,ok = QInputDialog.getText(self, "露点仪数据", "按如下格式记录:  RH空格T示例:  RH(0~100):66.6  T(0~200):9.8  输入:66.6 9.8", QLineEdit.Normal, "66.6 9.8" )            if ok == True:                data = re.findall('^[0-9]+.[0-9]+s+[0-9]+.[0-9]+$', data.rstrip())                if len(data) == 0:                    self.showMsgbox('数据格式有误,重新录入')                else:                    data = data[0].split()                    print(data)                    self.datadict['RHldy'] = data[0]                    self.datadict['Tldy'] = data[1]                    if self.getMCUdata() is None:                        return None                    print(self.datadict)                    self.insertTableNewLine()            else:                self.showMsgbox('请重新录入数据')    def showMsgbox(self,strtoshow):        QMessageBox.warning(self,'提示',strtoshow,QMessageBox.Ok)    def saveMsg(self):        file,ok = QFileDialog.getSaveFileName(self,"保存记录表","C:/",".txt")    def ScomAutoFind(self):        self.pushButton.setDisabled(True)        self.scomList = list(serial.tools.list_ports.comports())        if len(self.scomList) <p>由于我用的是RS232转USB接入电脑,设备名称是USB-SERIAL CH340,当然还有其他RS232转USB芯片,如PL2303等。我这里就单独检查USB是否在设备名称中,没有检查全名,这里要根据实际需求变动 <br><img src="https://img.php.cn/upload/article/000/099/200/03dff44dd0c61b3ad0a27af7058eadaf-3.png" alt="这里写图片描述" title=""><br>最后就是main了,没什么特别</p><pre class="brush:php;toolbar:false;">if __name__ == "__main__":    app = QApplication(sys.argv)    myshow = MyWindow()    myshow.show()    print('程序终止')    sys.exit(app.exec_())

看一下实际运行效果:
实际运行,(忽略 添加数据 与 数据记录表….)

点击connect后,

当然点击添加数据也是没问题的哈

奉上全部工程文件,链接如下:
https://download.csdn.net/download/ysgjiangsu/10324162