이 글은 주로 Python의 PyQT 다중 스레드 직렬 포트 코드 분석을 소개합니다. 편집자는 꽤 좋다고 생각하므로 지금 공유하고 참고용으로 제공하겠습니다. 에디터와 함께 구경해보세요
이 블로그는 주로 PyQT 멀티스레드 직렬 포트의 주요 코드 분석을 기록하고 있습니다. 글 마지막 부분에 프로젝트의 소스 코드 파일이 있을 것입니다
먼저 PyCharm에서 QtDesigner를 시작하세요
이것은 이전에 고객을 위해 수행되었습니다. 호스트 컴퓨터에서는 기밀 유지를 위해 대부분의 블록 다이어그램 구성 요소가 삭제되었지만 이는 이 직렬 포트 튜토리얼에 영향을 미치지 않습니다.
QtDesigner 인터페이스는 다음과 같습니다.
데이터 추가 및 테이블 데이터 표시를 무시합니다. 여기서는 사용되지 않습니다.
클래스 구성에 집중
QtCore.QThread에서 상속된 새 직렬 포트 클래스 SerialThread를 생성하여 모든 직렬 포트 트랜시버 기능을 실현합니다.
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 > 0: data = self.m_serialPort.read(n).decode('GB2312',errors='ignore') return data def run(self): cnt = 50 while cnt <= 3000: sendstr = str(cnt) if len(sendstr) == 2: sendstr = '00' + sendstr else: if len(sendstr) == 3: sendstr = '0' + sendstr self.ScomSendOneData('SET' + sendstr + 'V') cnt = cnt + 5 print('此时设置电压为:' + sendstr + 'V') time.sleep(2)
기능이 잘됩니다. -이름으로 알려져 있으며 여기에는 표시되지 않습니다. 여기서는 주로 run 함수에 대해 이야기합니다. run 함수는 50에서 3000까지 5단계를 진행하는 루프를 구현하며 전송되는 내용은 SET0050V에서 SET3000V입니다. 물론 이 기능이 필요하지 않은 경우에는 이렇게 합니다. , run 함수는
def run(self): while true: time.sleep(2)
Interface 로 작성할 수 있습니다. 우리는 QtDesigner에서 만든 ui 파일을 사용하여 pyUIC를 통해 py 파일을 생성합니다
생성된 코드는 다음과 같습니다(너무 길어서 처음 몇 줄만 남습니다)
# -*- 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): ** ** **
이번에는 QMainWindow와 Ui_cash를 상속받아 새로운 MyWindow 클래스를 생성하고, 클래스 내부에 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, "露点仪数据", "按如下格式记录:\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: 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) <= 0: self.showMsgbox('未发现串口,请检查线缆连接') self.pushButton.setDisabled(False) else: comNum = len(self.scomList) print(str(comNum) + 'Scom is found') while comNum: comNum = comNum - 1 if "USB" in str(self.scomList[comNum]): self.ThreadComID = SerialThread(portName=self.scomList[comNum][0]) self.ThreadComID.start() self.graphicsView.setStyleSheet("background-color: rgb(0, 255, 0);") print(str(self.scomList[comNum]) + ' is added')
RS232 to USB를 사용하여 컴퓨터에 연결하기 때문에 , 장치 이름은 USB-SERIAL CH340입니다. 물론 PL2303 등과 같은 다른 RS232-USB 칩도 있습니다. 여기서는 전체 이름을 확인하지 않고 USB가 장치 이름에만 있는지 확인합니다. 이것은 실제 필요에 따라 변경해야 합니다.
마지막은 메인이고 특별한 것은 없습니다
if __name__ == "__main__": app = QApplication(sys.argv) myshow = MyWindow() myshow.show() print('程序终止') sys.exit(app.exec_())
실제 실행 효과를 보세요:
실제 실행 중, (데이터 기록 테이블로 데이터 추가 무시...)
연결을 클릭한 후
물론 클릭하여 데이터를 추가해도 문제 없습니다.
여기에 모든 프로젝트 파일이 있습니다. 링크는 다음과 같습니다:
https://download.csdn.net /download/ysgjiangsu/10324162
위 내용은 Python PyQT 다중 스레드 직렬 포트 코드 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!