ホームページ >バックエンド開発 >Python チュートリアル >Python PyQT マルチスレッド シリアル ポート コード分析
この記事では主に Python の PyQT マルチスレッド シリアル ポート コード解析を紹介します。編集者が非常に優れていると考えたので、参考として共有します。エディターと一緒に覗いてみてください
このブログは主にPyQTマルチスレッドシリアルポートのメインコード解析を記録しています
プロジェクトのソースコードファイルは記事の最後にあります
これは以前に顧客向けに行われたものです。ホスト コンピューターでは、機密保持のため、ブロック図コンポーネントのほとんどが削除されていますが、これはこのシリアル ポート チュートリアルには影響しません。
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 に進み、コンテンツを 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 to 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 中国語 Web サイトの他の関連記事を参照してください。