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()))
result16 = str(self.ser.read(), encoding="utf8")[6:14] # 去掉从站号功能码crc校验码等,只保留读取值
print(result16)
if len(result16) == 0:
reply = QMessageBox.warning(self,
"地址读取空",
"请检查串口设置",
QMessageBox.Yes | QMessageBox.No)
elif keyName == 'DN': # 获取从站地址
# result10 = int('0x' + result16[2:], 16) # 先实现只读后两位
result10 = Func.hex8ToInt(result16)
self.AdrlineEdit.setText(result10)

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

996

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



