当前位置:Gxlcms > Python > Python之PyQT多线程串口代码分析

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

时间:2021-07-01 10:21:17 帮助过:41人阅读

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

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


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


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

  1. class SerialThread(QtCore.QThread):
  2. dataReadoutSignal = pyqtSignal(str) def __init__(self, parent = None, portName = 'COM3', baudrate = 9600, parity = 'N', bytesize = 8, stopbits = 1, timeout = None):
  3. super(SerialThread, self).__init__(parent)
  4. self.m_serialPort = serial.Serial()
  5. self.m_serialPort.port = portName
  6. self.m_serialPort.baudrate = baudrate
  7. self.m_serialPort.parity = parity
  8. self.m_serialPort.bytesize = bytesize
  9. self.m_serialPort.stopbits = stopbits
  10. self.m_serialPort.timeout = timeout
  11. self.OpenScom() def OpenScom(self):
  12. try:
  13. self.m_serialPort.open()
  14. self.m_serialPort.setRTS(True)
  15. self.m_serialPort.setDTR(True) except Exception as ex:
  16. print(ex) return ex def ScomSendOneData(self,datain):
  17. if isinstance(datain,int):
  18. listTemp = []
  19. listTemp.append(datain)
  20. d = bytes(listTemp)
  21. self.m_serialPort.write(d) else: if isinstance(datain,str):
  22. d = datain.encode('utf-8')
  23. self.m_serialPort.write(d) def ScomGetintData(self):
  24. n = self.m_serialPort.inWaiting() if n:
  25. data = self.m_serialPort.read(n).hex() #writefile
  26. print(data) def ScomGetstrData(self):
  27. if self.m_serialPort.is_open:
  28. n = self.m_serialPort.inWaiting() if n > 0:
  29. data = self.m_serialPort.read(n).decode('GB2312',errors='ignore') return data def run(self):
  30. cnt = 50
  31. while cnt <= 3000:
  32. sendstr = str(cnt) if len(sendstr) == 2:
  33. sendstr = '00' + sendstr else: if len(sendstr) == 3:
  34. sendstr = '0' + sendstr
  35. self.ScomSendOneData('SET' + sendstr + 'V')
  36. cnt = cnt + 5
  37. print('此时设置电压为:' + sendstr + 'V')
  38. time.sleep(2)

函数功能见名知意,此处不表。这里主要讲一下run函数,run函数实现了一次循环,50到3000步进取5,发送内容是SET0050V到SET3000V,当然,我这样做是业务需求,如果并不需要这个功能,run函数可以写成

  1. def run(self):
  2. while true:
  3. time.sleep(2)

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


这里写图片描述
生成的代码如下(太长,只留前几行)

  1. # -*- 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):
  2. def setupUi(self, cash):
  3. **
  4. **
  5. **

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

  1. class MyWindow(QMainWindow,Ui_cash):
  2. def __init__(self):
  3. super(MyWindow,self).__init__()
  4. self.scomList = []
  5. self.threadList = []
  6. self.setupUi(self)
  7. self.actionOpen.triggered.connect(self.openMsg)
  8. self.actionSave.triggered.connect(self.saveMsg)
  9. self.pushButton.clicked.connect(self.ScomAutoFind)
  10. self.addDataButton.clicked.connect(self.getRHandT)
  11. self.tableWidget.setColumnCount(5)
  12. self.tableWidget.setRowCount(1)
  13. self.tableWidget.setHorizontalHeaderLabels(['11', '22', '33', '44', '55'])
  14. self.tableRowCnt = 0
  15. self.tableColumnCnt = 0
  16. self.ThreadComID = 0
  17. self.addDatasignal = pyqtSignal(str)
  18. self.datadict = {'RHldy':0,'Tldy':0,'meaRT':0,'voltport':0} def getMCUdata(self):
  19. if self.ThreadComID == 0:
  20. self.showMsgbox('请先连接串口') else:
  21. self.ThreadComID.ScomSendOneData(' 5501AA')
  22. time.sleep(0.1)
  23. strt = self.ThreadComID.ScomGetstrData() if strt is None:
  24. self.showMsgbox('请将串口线连接到电路板') return None
  25. print(strt)
  26. self.datadict['voltport'] = strt[4:-3] + '.' + strt[-3:-2]
  27. self.ThreadComID.ScomSendOneData(' 5502AA')
  28. time.sleep(0.1)
  29. strt = self.ThreadComID.ScomGetstrData() if strt is None:
  30. self.showMsgbox('请将串口线连接到电路板') return None
  31. print(strt)
  32. self.datadict['meaRT'] = strt[4:-4] + '.' + strt[-4:-2] return 1
  33. def insertTableNewLine(self):
  34. self.tableWidget.setItem(self.tableRowCnt, 0, QTableWidgetItem(self.datadict['RHldy']))
  35. self.tableWidget.setItem(self.tableRowCnt, 1, QTableWidgetItem(self.datadict['Tldy']))
  36. self.tableWidget.setItem(self.tableRowCnt, 2, QTableWidgetItem(self.datadict['meaRT']))
  37. self.tableWidget.setItem(self.tableRowCnt, 3, QTableWidgetItem(self.datadict['voltport']))
  38. self.tableWidget.setItem(self.tableRowCnt, 4, QTableWidgetItem(str(datetime.date.today())+' '+str(datetime.datetime.today().hour)+':'+str(datetime.datetime.today().minute)))
  39. self.tableRowCnt += 1
  40. self.tableWidget.insertRow(self.tableRowCnt) def openMsg(self):
  41. file,ok = QFileDialog.getOpenFileName(self,"打开记录表","C:/",".txt") def getRHandT(self):
  42. if self.ThreadComID == 0:
  43. self.showMsgbox('请先连接串口') else:
  44. data,ok = QInputDialog.getText(self, "露点仪数据", "按如下格式记录:\n RH空格T\n示例:\n RH(0~100):66.6\n T(0~200):9.8\n 输入:66.6 9.8", QLineEdit.Normal, "66.6 9.8" ) if ok == True:
  45. data = re.findall('^[0-9]+\.[0-9]+\s+[0-9]+\.[0-9]+$', data.rstrip()) if len(data) == 0:
  46. self.showMsgbox('数据格式有误,重新录入') else:
  47. data = data[0].split()
  48. print(data)
  49. self.datadict['RHldy'] = data[0]
  50. self.datadict['Tldy'] = data[1] if self.getMCUdata() is None: return None
  51. print(self.datadict)
  52. self.insertTableNewLine() else:
  53. self.showMsgbox('请重新录入数据') def showMsgbox(self,strtoshow):
  54. QMessageBox.warning(self,'提示',strtoshow,QMessageBox.Ok) def saveMsg(self):
  55. file,ok = QFileDialog.getSaveFileName(self,"保存记录表","C:/",".txt") def ScomAutoFind(self):
  56. self.pushButton.setDisabled(True)
  57. self.scomList = list(serial.tools.list_ports.comports()) if len(self.scomList) <= 0:
  58. self.showMsgbox('未发现串口,请检查线缆连接')
  59. self.pushButton.setDisabled(False) else:
  60. comNum = len(self.scomList)
  61. print(str(comNum) + 'Scom is found') while comNum:
  62. comNum = comNum - 1
  63. if "USB" in str(self.scomList[comNum]):
  64. self.ThreadComID = SerialThread(portName=self.scomList[comNum][0])
  65. self.ThreadComID.start()
  66. self.graphicsView.setStyleSheet("background-color: rgb(0, 255, 0);")
  67. print(str(self.scomList[comNum]) + ' is added')

由于我用的是RS232转USB接入电脑,设备名称是USB-SERIAL CH340,当然还有其他RS232转USB芯片,如PL2303等。我这里就单独检查USB是否在设备名称中,没有检查全名,这里要根据实际需求变动
这里写图片描述
最后就是main了,没什么特别

  1. if __name__ == "__main__":
  2. app = QApplication(sys.argv)
  3. myshow = MyWindow()
  4. myshow.show() print('程序终止')
  5. sys.exit(app.exec_())

看一下实际运行效果:
实际运行,(忽略 添加数据 与 数据记录表….)
这里写图片描述
点击connect后,
这里写图片描述
当然点击添加数据也是没问题的哈
这里写图片描述

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

以上就是Python之PyQT多线程串口代码分析的详细内容,更多请关注Gxl网其它相关文章!

人气教程排行