Test.py实现GUI界面和大部分逻辑
# -*- coding: utf-8 -*-
from PyQt5.QtCore import QDateTime, Qt, QTimer, pyqtSignal, QThread
from PyQt5.QtWidgets import (QApplication, QCheckBox, QComboBox, QDateTimeEdit,
QDial, QDialog, QGridLayout, QGroupBox, QHBoxLayout, QLabel, QLineEdit,
QProgressBar, QPushButton, QRadioButton, QScrollBar, QSizePolicy,
QSlider, QSpinBox, QStyleFactory, QTableWidget, QTabWidget, QTextEdit,
QVBoxLayout, QWidget, QMessageBox)
from PyQt5.QtGui import (QIntValidator)
import serial
import serial.tools.list_ports
import crcmod.predefined
import Func
import time
import threading
class WidgetGallery(QDialog):
# global dict1
# dict1 = {'SUM': '0000'}
sig = pyqtSignal(str, str, float, str, str, str)
def __init__(self, parent=None):
super(WidgetGallery, self).__init__(parent)
self.originalPalette = QApplication.palette()
self.comComboBox = QComboBox()
# print(self.getPort())
# self.comComboBox.currentIndexChanged.connect(self.selectionchange)
# print(self.comComboBox.currentText())
self.pasg = '1' # 默认通道为1,不然初始化bug
self.serFlag = False
comLabel = QLabel("串口:")
comLabel.setBuddy(self.comComboBox)
self.bpsComboBox = QComboBox()
self.bpsComboBox.addItems(self.getBps())
bpsLabel = QLabel("波特率:")
bpsLabel.setBuddy(self.bpsComboBox)
self.crcComboBox = QComboBox()
self.crcComboBox.addItems(self.getCrc())
crcLabel = QLabel("校验:")
crcLabel.setBuddy(self.crcComboBox)
self.openButton = QPushButton("打开串口")
self.openButton.setDefault(False)
self.openButton.clicked.connect(self.openSer)
self.openButton.setCheckable(True)
# self.openButton.setAutoExclusive(True)
# self.openButton.setEnabled(False)
# print(self.getPort())
self.comComboBox.addItems(self.getPort())
# self.open1Button = QPushButton("go03")
# self.open1Button.setDefault(False)
# self.staNum = '01'
# self.funCode = '03'
# self.keyName = 'SUM'
# self.open1Button.clicked.connect(self.sendFunction03(staNum, funCode, keyName))
# self.open1Button.clicked.connect(self.Print)
# self.open1Button.clicked.connect(self.sendFunction03)
self.setWindowFlags(Qt.Widget)
self.setWindowTitle("ST05D校准软件")
self.resize(600, 400)
self.setFixedSize(600, 400)
self.changeStyle('windowsvista')
topLayout = QHBoxLayout()
topLayout.addWidget(comLabel)
topLayout.addWidget(self.comComboBox)
topLayout.addWidget(bpsLabel)
topLayout.addWidget(self.bpsComboBox)
topLayout.addWidget(crcLabel)
topLayout.addWidget(self.crcComboBox)
topLayout.addSpacing(50)
topLayout.addWidget(self.openButton)
# topLayout.addWidget(self.open1Button)
topLayout.addStretch(1)
self.createTopLeftGroupBox()
self.createTopRightGroupBox()
self.createMiddleLeftGroupBox()
self.createMiddleRightGroupBox()
self.createBottomLeftGroupBox()
self.createBottomRightGroupBox()
mainLayout = QGridLayout()
mainLayout.addLayout(topLayout, 0, 0, 1, 2)
mainLayout.addWidget(self.topLeftGroupBox, 1, 0)
mainLayout.addWidget(self.topRightGroupBox, 1, 1)
mainLayout.addWidget(self.middleLeftGroupBox, 2, 0)
mainLayout.addWidget(self.middleRightGroupBox, 2, 1)
mainLayout.addWidget(self.bottomLeftGroupBox, 3, 0)
mainLayout.addWidget(self.bottomRightGroupBox, 3, 1)
mainLayout.setColumnStretch(0, 1)
mainLayout.setColumnStretch(1, 1)
self.setLayout(mainLayout)
# def Print(self):
# print('print')
def closeEvent(self, event):
# self.c.terminate()
print('thread=sta', self.readthread._running)
self.readthread.terminate()
print('close')
def openSer(self):
print('open')
print(self.openButton.isChecked())
if self.openButton.isChecked():
self.ser = serial.Serial(self.comComboBox.currentText(), self.bpsComboBox.currentText(), timeout=0)
self.comComboBox.setEnabled(False)
self.bpsComboBox.setEnabled(False)
self.crcComboBox.setEnabled(False)
self.openButton.setText('关闭串口')
else:
print('no')
self.ser.close()
self.openButton.setText('打开串口')
self.comComboBox.setEnabled(True)
self.bpsComboBox.setEnabled(True)
self.crcComboBox.setEnabled(True)
# if not self.serFlag:
# self.ser = serial.Serial(self.comComboBox.currentText(), self.bpsComboBox.currentText(), timeout=0)
# self.serFlag = True
# print(self.comComboBox.currentText(), self.bpsComboBox.currentText())
# else:
# self.ser.close()
# self.serFlag = False
# self.openSer()
# def sendFunction03(self, staNum, funCode, keyName):
def send03(self, keyName):
try:
staNum = self.staNum
# funCode = self.funCode
# keyName = self.keyName
except Exception:
staNum = '00'
# keyName = self.keyName
funCode = '03'
print('033')
if self.openButton.isChecked():
list1 = Func.sendFunction03(staNum, funCode, keyName)
# list1 = []
# dict1 = Func.addressDict03
# list1.append(int('0x' + staNum, 16))
# list1.append(int('0x' + funCode, 16))
# list1.append(int('0x' + dict1[keyName][0:2], 16))
# list1.append(int('0x' + dict1[keyName][2:4], 16))
# list1.append(int('0x00', 16))
# list1.append(int('0x02', 16))
# crc16_func = crcmod.predefined.mkCrcFun('modbus')
# # ba = bytearray([0o01, 0o03, 0o00, 0o00, 0o00, 0o02])
# a = bytes().fromhex(staNum + funCode + dict1[keyName] + '0002')
# # print(a)
# reslist = hex(crc16_func(a))[2:].zfill(4)
# # print(type(reslist[2:].upper()), reslist[:2].upper())
# list1.append(int('0x' + reslist[2:], 16))
# list1.append(int('0x' + reslist[:2], 16))
print(list1)
try:
self.ser.write(list1)
except Exception:
print('not ok')
reply = QMessageBox.warning(self,
"串口设置错误",
"请检查串口号及波特率设置",
QMessageBox.Yes | QMessageBox.No)
# self.echo(reply)
else:
print(type(self.ser.read()))

本文通过PyQt5构建GUI界面,并结合pyserial库,详细介绍了如何使用Python实现Modbus串口通信。同时,利用QThread确保UI线程不被阻塞,保证了用户体验。Func.py文件中包含了具体的Modbus交互指令和CRC校验功能。
最低0.47元/天 解锁文章
4630

被折叠的 条评论
为什么被折叠?



