使用pyserial开发的一个串口调试工具

前言

前段时间因为做一个项目需要用到串口传输数据,学习了一些串口的基本知识。现在忙里偷闲,突然心血来潮,花了一点时间用python开发了一个简单的串口调试工具,可以实现基本的串口开关、配置、收发数据功能。感兴趣的朋友可以从:https://pan.baidu.com/s/1HQEuuu-7irLvBi9NLBHa3A, 免费获取,提取码:dvli
当然这是一个初开发的软件,还有一些bug尚待完善,界面也不够优美。如果有朋友在使用中遇到可以在我的博客下留言,后续会开放源代码,本人也会逐渐完善功能,优化界面。软件界面如下:

在这里插入图片描述

开发环境

编程语言:Python3.6
开发工具:PyCharm + PyQt5
开发系统:Windows10

代码实现

有关pyserial的内容网上很多地方都有,可以参考这篇博客python库之pyserial用法。项目共包含四个文件,下面会分别说明四个文件的作用。话不多说,直接上代码!

port.py

这个python文件里面是我重写的serial类

import serial


class COM:
    def __init__(self, port):
        self.ser = None
        self.port = port
        self.port_state = True

    # 检查串口是否可用
    def check_port_state(self):
        try:
            self.ser = serial.Serial(self.port)
            self.ser.close()
        except serial.SerialException as se:
            self.port_state = False
            print(se)
        return self.port_state

    # 打开串口
    def open_port(self):
        try:
            if self.check_port_state():
                self.ser.open()
        except Exception as e:
            print(e)

    # 关闭串口
    def close_port(self):
        try:
            if self.port_state and self.ser.isOpen():
                self.ser.close()
        except serial.SerialException as se:
            print(se)

    # 设置波特率
    def set_baud_rate(self, baud_rate):
        try:
            self.ser.baudrate = int(baud_rate)
        except ValueError as ve:
            print(ve)

    # 设置数据位
    def set_byte_size(self, byte_size):
        try:
            if int(byte_size) == 5:
                self.ser.bytesize = serial.FIVEBITS
            elif int(byte_size) == 6:
                self.ser.bytesize = serial.SIXBITS
            elif int(byte_size) == 7:
                self.ser.bytesize = serial.SEVENBITS
            elif int(byte_size) == 8:
                self.ser.bytesize = serial.EIGHTBITS
        except ValueError as e:
            print(e)

    # 设置停止位
    def set_stop_bits(self, stop_bits):
        try:
            if stop_bits == '1':
                self.ser.stopbits = serial.STOPBITS_ONE
            # elif stop_bits == '1.5':
            #     self.ser.stopbits = serial.STOPBITS_ONE_POINT_FIVE
            elif stop_bits == '2':
                self.ser.stopbits = serial.STOPBITS_TWO
        except ValueError as e:
            print(e)

    # 设置校验位
    def set_parity(self, parity):
        try:
            if parity == 'NONE':
                self.ser.parity = serial.PARITY_NONE
            elif parity == 'EVEN':
                self.ser.parity = serial.PARITY_EVEN
            elif parity == 'ODD':
                self.ser.parity = serial.PARITY_ODD
            elif parity == 'MARK':
                self.ser.parity = serial.PARITY_MARK
            elif parity == 'SPACE':
                self.ser.parity = serial.PARITY_SPACE
        except ValueError as e:
            print(e)

    # 获取流控制状态
    def set_flow_ctr(self, flow_ctr):
        try:
            if flow_ctr == 'Software:xonxoff':
                self.ser.rtscts = False
                self.ser.dsrdtr = False
                self.ser.xonxoff = True
            elif flow_ctr == 'Hardware:rtscts':
                self.ser.xonxoff = False
                self.ser.dsrdtr = False
                self.ser.rtscts = True
            elif flow_ctr == 'Hardware:dsrdtr':
                self.ser.xonxoff = False
                self.ser.rtscts = False
                self.ser.dsrdtr = True
        except Exception as e:
            print(e)

    # 设置 DTR
    def set_dtr(self, dtr):
        try:
            if dtr:
                self.ser.setDTR(True)
            else:
                self.ser.setDTR(False)
        except Exception as e:
            print(e)

    # 设置 RTS
    def set_rts(self, rts):
        try:
            if rts:
                self.ser.setRTS(True)
            else:
                self.ser.setRTS(False)
        except Exception as e:
            print(e)

    # 发送数据
    def send_data(self, data):
        send_bytes = 0
        if self.ser is None:
            self.open_port()
        try:
            send_bytes = self.ser.write(data)
        except Exception as e:
            print(e)
        return send_bytes

    # 读取串口数据
    def get_data(self):
        data = ''
        try:
            if self.ser is None:
                self.open_port()
            data = self.ser.read(self.ser.inWaiting()).decode()
        except Exception as e:
            print(e)
        if data != '':
            return data

method.py

这个python文件里面是一些串口的参数设置和方法

import binascii
import serial
import serial.tools.list_ports


# 获取串口列表
def get_port_list():
    port_dict = {}
    port_list = []
    list_port = list(serial.tools.list_ports.comports())
    if len(list_port) == 0:
        print("无可用串口!")
    else:
        for i in range(len(list_port)):
            port_dict[i] = str(list_port[i])[:4]
    for key, value in port_dict.items():
        temps = value
        port_list.append(temps)
    return port_list


# 波特率
def get_baud_rate():
    baud_rate_list = ['110', '300', '600', '1200', '2400', '4800', '9600', '14400', '19200', '38400', '56000',
                      '57600', '115200', '128000', '256000']
    return baud_rate_list


# 数据位
def get_byte_size():
    byte_size_list = ['5', '6', '7', '8']
    return byte_size_list


# 停止位
def get_stop_bits():
    stop_bits_list = ['1', '1.5', '2']
    return stop_bits_list


# 校验位
def get_parity():
    parity_list = ['NONE', 'EVEN', 'ODD', 'MARK', 'SPACE']
    return parity_list


# 流控制
def get_flow_ctr():
    flow_list = ['None', 'Software:xonxoff', 'Hardware:rtscts', 'Hardware:dsrdtr']
    return flow_list


# str转hex
def str_hex(str_data):
    hex_data = ''
    data_len = len(str_data)
    for i in range(data_len):
        h_vol = ord(str_data[i])
        h_hex = '%02x' % h_vol
        hex_data += h_hex + ' '
    return hex_data


# hex转str
def hex_str(hex_data):
    data_list = hex_data.split()
    data_str = "".join(data_list)
    m = data_str.encode('utf-8')
    str_data = binascii.unhexlify(m)
    return str_data.decode('utf-8')


# bytes转hex
def byte_hex(byte_data):
    hex_data = ''
    for item in byte_data:
        hex_data += str(hex(item))[2:].zfill(2).upper() + " "
    return hex_data


# hex转bytes
def hex_byte(hex_data):
    byte_data = []
    s_list = hex_data.split(' ')
    for i in s_list:
        b = int(i, 16)
        byte_data.append(b)
    return byte_data


# 检查hex格式
def check_hex(data):
    flag = True
    sub_data = []
    for i in range(len(data)):
        if (i+1) % 3 == 0:
            sub_data.append(data[i])
    for item in sub_data:
        if item != ' ':
            flag = False
    return flag

main.py

这个python文件是程序运行的文件

import os
import sys

from PyQt5 import QtCore, QtGui
from PyQt5.QtCore import QTimer
from PyQt5.QtGui import QIcon, QPainter, QColor, QFont

import method
import port
from PyQt5.QtWidgets import QApplication, QMainWindow, QFileDialog, QMessageBox
from sscom import Ui_MainWindow


class MyMainForm(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MyMainForm, self).__init__(parent)
        self.setupUi(self)
        self.setWindowTitle('Serial Tool V1.0)   # 设置窗体标题
        self.setWindowIcon(QIcon(r'.\imgs\title2.ico'))   # 设置窗体图标
        self.loopSendBox.setEnabled(False)    # 锁定定时发送
        self.init_port()                      # 初始化调用init_port()函数
        self.init_config()                    # 初始化调用init_config()函数
        self.init_send_show()                 # 初始化调用init_send_show()函数
        self.init_file()                      # 初始化调用init_file()函数

    # 串口开关控件初始化
    def init_port(self):
        self.myCOM = None
        self.portItemsBox.addItems(method.get_port_list())                            # 获取可以串口列表并添加到串口号下拉框
        self.openPortBtn.setChecked(False)                                            # 设置打开串口按钮初始值为关闭
        self.openPortBtn.toggled.connect(lambda: self.btn_port(self.openPortBtn))     # 打开串口按钮绑定槽函数
        self.closePortBtn.setChecked(True)                                            # 设置关闭串口按钮初始值为打开
        self.closePortBtn.toggled.connect(lambda: self.btn_port(self.closePortBtn))   # 关闭串口按钮绑定槽函数

    # 串口配置控件初始化
    def init_config(self):
        self.baudBox.addItems(method.get_baud_rate())           # 波特率下拉框添加选项
        self.baudBox.setCurrentIndex(6)                         # 波特率下拉框设置初始索引
        self.baudBox.activated.connect(self.config_port)        # 波特率下拉框绑定config_port函数
        self.byteBox.addItems(method.get_byte_size())           # 数据位下拉框添加选项
        self.byteBox.setCurrentIndex(3)                         # 数据位下拉框设置初始索引
        self.byteBox.activated.connect(self.config_port)        # 数据位下拉框绑定config_port函数
        self.stopBitBox.addItems(method.get_stop_bits())        # 停止位下拉框添加选项
        self.stopBitBox.activated.connect(self.config_port)     # 停止位下拉框绑定config_port函数
        self.parityBox.addItems(method.get_parity())            # 校验位下拉框添加选项
        self.parityBox.activated.connect(self.config_port)      # 校验位下拉框绑定config_port函数
        self.flowCtrBox.addItems(method.get_flow_ctr())         # 流控制下拉框添加选项
        self.flowCtrBox.activated.connect(self.config_port)     # 流控制下拉框绑定config_port函数
        self.DTRBox.stateChanged.connect(self.set_dtr)          # DTR复选框绑定set_dtr函数
        self.RTSBox.stateChanged.connect(self.set_rts)          # RTS复选框绑定set_rts函数

    # 收发数据控件初始化
    def init_send_show(self):
        self.showDataEdit.setReadOnly(True)                               # 设置显示数据文本框为只读
        self.timer_show = QTimer(self)                                    # 定义一个定时接收器
        self.timer_show.timeout.connect(self.show_data)                   # 定时接收器绑定show_data函数
        self.HEXShowBox.setChecked(False)                                 # HEX显示复选框设置为不选中
        self.HEXShowBox.stateChanged.connect(lambda: self.show_type())    # HEX显示复选框绑定show_type函数
        self.timer_send = QTimer(self)                                    # 定义一个定时发送器
        self.timer_send.timeout.connect(self.send_data_loop)              # 定时发送器绑定send_data_loop函数
        self.loopSendBox.toggled.connect(self.send_data_loop)             # 定时发送复选框绑定send_data_loop函数
        self.sendDataBtn.clicked.connect(self.send_data)                  # 发送数据按钮绑定send_data函数
        self.clearWinBtn.clicked.connect(self.clear_win)                  # 清除窗口按钮绑定clear_win函数
        self.all_send_bytes = 0                                           # 定义一个总发送字节数
        self.all_get_bytes = 0                                            # 定义一个总接收字节数

    # 打开文件控件初始化
    def init_file(self):
        self.openFileBtn.clicked.connect(self.open_file)    # 打开文件按钮绑定open_file函数
        self.fileDialog = QFileDialog                       # 定义一个打开文件弹窗
        self.sendFileBtn.clicked.connect(self.send_file)    # 打开文件按钮绑定send_file函数

    # 打开串口
    def open_port(self):
        try:
            self.myCOM = port.COM(self.portItemsBox.currentText())    # 实例化一个自定义的port类
            self.myCOM.open_port()                                    # 打开串口
            self.portItemsBox.setEnabled(False)                       # 锁定串口下拉框
            if not self.myCOM.port_state:                             # 如果串口不可用,弹窗报错
                port_error_msgBox = QMessageBox(QMessageBox.Information, '串口打开错误', '串口无法打开,当前串口已被占用或其他错误!!'
                                                                                   '请选择其他串口或检查串口设置是否正确。')
                port_error_msgBox.setWindowIcon(QIcon(r'D:\WorkSpace\MyData\Python\串口1.0\imgs\error.ico'))
                port_error_msgBox.exec_()
                self.closePortBtn.setChecked(True)                    # 选择关闭按钮
                self.portItemsBox.setEnabled(True)                    # 解除串口下拉框锁定
            self.DTRBox.setChecked(self.myCOM.ser.dtr)                # 获取DTR
            self.RTSBox.setChecked(self.myCOM.ser.rts)                # 获取RTS
            self.timer_show.start(2)                                  # 打开接收定时器,设置每隔2毫秒接收一次
            port_info1 = self.myCOM.ser.port + '已打开' + ' [' + str(self.myCOM.ser.baudrate) + '-' + str(self.myCOM.ser.bytesize) + \
                        '-' + str(self.myCOM.ser.stopbits) + '-' + self.myCOM.ser.parity + ']'
            port_info2 = ' [CTS=' + str(self.myCOM.ser.getCTS()) + ' DSR=' + str(self.myCOM.ser.getDSR()) + ' RI=' + \
                         str(self.myCOM.ser.getRI()) + ' CD=' + str(self.myCOM.ser.getCD()) + ']'
            self.portInfolabel.setText(port_info1 + port_info2)       # 显示已打开串口信息
        except Exception as e:
            print(e)

    # 关闭串口
    def close_port(self):
        try:
            self.timer_show.stop()                                      # 关闭接收定时器
            self.myCOM.close_port()                                     # 关闭串口
            self.DTRBox.setChecked(False)
            self.RTSBox.setChecked(False)
            self.portItemsBox.setEnabled(True)                          # 解除串口下拉框锁定
            self.portInfolabel.setText(self.myCOM.ser.port + '已关闭')
        except Exception as e:
            print(e)

    # 打开还是关闭串口
    def btn_port(self, btn):
        if btn.text() == '打开串口':
            if btn.isChecked():
                self.open_port()                     # 打开串口
                self.loopSendBox.setEnabled(True)    # 解除定时发送复选框锁定
            else:
                self.close_port()                    # 关闭串口
                self.loopSendBox.setEnabled(False)   # 锁定定时发送复选框

    # 配置串口
    def config_port(self):
        try:
            self.myCOM.set_baud_rate(self.baudBox.currentText())       # 设置波特率
            self.myCOM.set_byte_size(self.byteBox.currentText())       # 设置数据位
            self.myCOM.set_stop_bits(self.stopBitBox.currentText())    # 设置停止位
            self.myCOM.set_parity(self.parityBox.currentText())        # 设置校验位
            self.myCOM.set_flow_ctr(self.flowCtrBox.currentText())     # 设置流控制
        except Exception as e:
            print(e)

    # 设置 DTR
    def set_dtr(self):
        try:
            self.myCOM.set_dtr(self.DTRBox.isChecked())
        except Exception as e:
            print(e)

    # 设置 RTS
    def set_rts(self):
        try:
            self.myCOM.set_rts(self.RTSBox.isChecked())
        except Exception as e:
            print(e)

    # 发送数据
    def send_data(self):
        try:
            data = self.sendDataEdit.text()      # 从发送数据输入框获取要发送的数据
            send_bytes = 0                       # 定义一个发送字节数
            if self.closePortBtn.isChecked():    # 如果关闭串口按钮选定,不能发送数据
                send_error_msgBox = QMessageBox(QMessageBox.Information, '发送数据错误', '无法发送数据,请先打开串口!')
                send_error_msgBox.setWindowIcon(QIcon(r'.\imgs\error.ico'))
                send_error_msgBox.exec_()
            else:
                if self.HEXSendBox.isChecked():  # 如果HEX发送复选框选定,发送HEX格式数据
                    if not method.check_hex(data) or len(''.join(data.split())) % 2 != 0:
                        hex_error_msgBox = QMessageBox(QMessageBox.Information, '发送数据错误', '输入hex格式错误! '
                                                                                          '请按照如“01 23 .. ..” 格式输入')
                        hex_error_msgBox.setWindowIcon(QIcon(r'.\imgs\error.ico'))
                        hex_error_msgBox.exec_()
                    else:
                        send_bytes = self.myCOM.send_data(method.hex_byte(data))  # 获取发送字节数
                else:
                    send_bytes = self.myCOM.send_data(data.encode())              # 获取发送字节数
                self.all_send_bytes += send_bytes                                 # 统计发送总字节数
                self.sendBytelabel.setText('S:' + str(self.all_send_bytes))
        except Exception as e:
            print(e)

    # 定时发送
    def send_data_loop(self):
        if self.loopSendBox.isChecked():                             # 如果定时发送复选框被选定,定时发送数据
            self.setTimeEdit.setReadOnly(True)                       # 定时发送输入框设置只读
            if self.setTimeEdit.text() != '':                        # 如果定时发送输入框输入不为空,设置间隔时间
                self.timer_send.start(int(self.setTimeEdit.text()))
                self.send_data()
        else:
            self.timer_send.stop()                                   # 停止定时发送定时器
            self.setTimeEdit.setReadOnly(False)                      # 取消定时发送输入框设置只读

    # 读取并显示数据
    def show_data(self):
        data = self.myCOM.get_data()             # 获取接收到的数据
        try:
            if data is not None:                 # 如果接收到的数据不为空,选择字符串显示还是HEX显示
                if self.HEXShowBox.isChecked():
                    self.showDataEdit.insertPlainText(method.str_hex(data))
                else:
                    self.showDataEdit.insertPlainText(data)
                self.all_get_bytes += len(data)  # 统计接收总字节数
                self.getBytelabel.setText('R:' + str(self.all_get_bytes))
        except Exception as e:
            print(e)
        text_cursor = self.showDataEdit.textCursor()   # 获取光标位置
        text_cursor.movePosition(text_cursor.End)
        self.showDataEdit.setTextCursor(text_cursor)   # 设置光标位置

    # 选择显示类型,str 还是 hex
    def show_type(self):
        if self.HEXShowBox.isChecked():
            text_data = self.showDataEdit.toPlainText()
            hex_data = method.str_hex(text_data)
            self.showDataEdit.setPlainText(hex_data)
        else:
            text_data = self.showDataEdit.toPlainText()
            data = method.hex_str(text_data)
            self.showDataEdit.setPlainText(data)
        text_cursor = self.showDataEdit.textCursor()
        text_cursor.movePosition(text_cursor.End)
        self.showDataEdit.setTextCursor(text_cursor)

    # 打开文件
    def open_file(self):
        try:
            file_name, file_type = self.fileDialog.getOpenFileName(self, '打开文件', os.getcwd(),
                                                                   'All Files(*);;Text Files(*.txt)')
            if file_name != '':
                self.fileNameEdit.setText(file_name)
                with open(file_name, 'r', encoding='utf-8') as f:
                    for line in f:
                        self.showDataEdit.insertPlainText(line)
        except Exception as e:
            print(e)

    # 发送文件
    def send_file(self):
        if self.closePortBtn.isChecked():
            send_error_msgBox = QMessageBox(QMessageBox.Information, '发送文件错误', '无法发送文件,请先打开串口!')
            send_error_msgBox.setWindowIcon(QIcon(r'.\imgs\error.ico'))
            send_error_msgBox.exec_()
        try:
            if self.fileNameEdit.text() != '':
                file_data = self.showDataEdit.toPlainText()
                send_bytes = self.myCOM.send_data(file_data.encode())
        except Exception as e:
            print(e)

    # 清除窗口
    def clear_win(self):
        self.showDataEdit.clear()
        self.sendBytelabel.setText('S:0')
        self.getBytelabel.setText('R:0')


if __name__ == "__main__":
    app = QApplication(sys.argv)
    myWin = MyMainForm()
    myWin.show()
    sys.exit(app.exec_())

sscom.py

这个python文件是画ui界面

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(631, 520)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.openFileBtn = QtWidgets.QPushButton(self.centralwidget)
        self.openFileBtn.setGeometry(QtCore.QRect(10, 380, 61, 31))
        self.openFileBtn.setObjectName("openFileBtn")
        self.fileNameEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.fileNameEdit.setGeometry(QtCore.QRect(100, 380, 411, 31))
        self.fileNameEdit.setObjectName("fileNameEdit")
        self.sendDataEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.sendDataEdit.setGeometry(QtCore.QRect(100, 340, 411, 31))
        self.sendDataEdit.setObjectName("sendDataEdit")
        self.sendFileBtn = QtWidgets.QPushButton(self.centralwidget)
        self.sendFileBtn.setGeometry(QtCore.QRect(530, 380, 71, 31))
        self.sendFileBtn.setObjectName("sendFileBtn")
        self.clearWinBtn = QtWidgets.QPushButton(self.centralwidget)
        self.clearWinBtn.setGeometry(QtCore.QRect(430, 300, 81, 31))
        self.clearWinBtn.setObjectName("clearWinBtn")
        self.portNamelabel = QtWidgets.QLabel(self.centralwidget)
        self.portNamelabel.setGeometry(QtCore.QRect(10, 40, 61, 21))
        self.portNamelabel.setObjectName("portNamelabel")
        self.sendDatalabel = QtWidgets.QLabel(self.centralwidget)
        self.sendDatalabel.setGeometry(QtCore.QRect(10, 340, 81, 31))
        self.sendDatalabel.setObjectName("sendDatalabel")
        self.sendDataBtn = QtWidgets.QPushButton(self.centralwidget)
        self.sendDataBtn.setGeometry(QtCore.QRect(530, 340, 71, 31))
        self.sendDataBtn.setObjectName("sendDataBtn")
        self.DTRBox = QtWidgets.QCheckBox(self.centralwidget)
        self.DTRBox.setGeometry(QtCore.QRect(10, 275, 71, 21))
        self.DTRBox.setObjectName("DTRBox")
        self.RTSBox = QtWidgets.QCheckBox(self.centralwidget)
        self.RTSBox.setGeometry(QtCore.QRect(100, 275, 71, 21))
        self.RTSBox.setObjectName("RTSBox")
        self.HEXSendBox = QtWidgets.QCheckBox(self.centralwidget)
        self.HEXSendBox.setGeometry(QtCore.QRect(10, 305, 81, 21))
        self.HEXSendBox.setObjectName("HEXSendBox")
        self.portItemsBox = QtWidgets.QComboBox(self.centralwidget)
        self.portItemsBox.setGeometry(QtCore.QRect(70, 40, 121, 22))
        self.portItemsBox.setObjectName("portItemsBox")
        self.baudBox = QtWidgets.QComboBox(self.centralwidget)
        self.baudBox.setGeometry(QtCore.QRect(70, 80, 121, 22))
        self.baudBox.setObjectName("baudBox")
        self.byteBox = QtWidgets.QComboBox(self.centralwidget)
        self.byteBox.setGeometry(QtCore.QRect(70, 120, 121, 22))
        self.byteBox.setObjectName("byteBox")
        self.stopBitBox = QtWidgets.QComboBox(self.centralwidget)
        self.stopBitBox.setGeometry(QtCore.QRect(70, 160, 121, 20))
        self.stopBitBox.setObjectName("stopBitBox")
        self.parityBox = QtWidgets.QComboBox(self.centralwidget)
        self.parityBox.setGeometry(QtCore.QRect(70, 200, 121, 22))
        self.parityBox.setObjectName("parityBox")
        self.flowCtrBox = QtWidgets.QComboBox(self.centralwidget)
        self.flowCtrBox.setGeometry(QtCore.QRect(70, 240, 121, 22))
        self.flowCtrBox.setObjectName("flowCtrBox")
        self.openPortBtn = QtWidgets.QRadioButton(self.centralwidget)
        self.openPortBtn.setGeometry(QtCore.QRect(10, 6, 89, 20))
        self.openPortBtn.setObjectName("openPortBtn")
        self.closePortBtn = QtWidgets.QRadioButton(self.centralwidget)
        self.closePortBtn.setGeometry(QtCore.QRect(110, 5, 89, 21))
        self.closePortBtn.setObjectName("closePortBtn")
        self.baudlabel = QtWidgets.QLabel(self.centralwidget)
        self.baudlabel.setGeometry(QtCore.QRect(10, 80, 61, 21))
        self.baudlabel.setObjectName("baudlabel")
        self.bytelabel = QtWidgets.QLabel(self.centralwidget)
        self.bytelabel.setGeometry(QtCore.QRect(10, 120, 61, 20))
        self.bytelabel.setObjectName("bytelabel")
        self.stopBitlabel = QtWidgets.QLabel(self.centralwidget)
        self.stopBitlabel.setGeometry(QtCore.QRect(10, 160, 61, 21))
        self.stopBitlabel.setObjectName("stopBitlabel")
        self.paritylabel = QtWidgets.QLabel(self.centralwidget)
        self.paritylabel.setGeometry(QtCore.QRect(10, 200, 61, 21))
        self.paritylabel.setObjectName("paritylabel")
        self.flowCtrlabel = QtWidgets.QLabel(self.centralwidget)
        self.flowCtrlabel.setGeometry(QtCore.QRect(10, 240, 61, 20))
        self.flowCtrlabel.setObjectName("flowCtrlabel")
        self.loopSendBox = QtWidgets.QCheckBox(self.centralwidget)
        self.loopSendBox.setGeometry(QtCore.QRect(100, 305, 91, 21))
        self.loopSendBox.setObjectName("loopSendBox")
        self.setTimeEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.setTimeEdit.setGeometry(QtCore.QRect(200, 306, 61, 20))
        self.setTimeEdit.setObjectName("setTimeEdit")
        self.setTimeLabel = QtWidgets.QLabel(self.centralwidget)
        self.setTimeLabel.setGeometry(QtCore.QRect(270, 305, 51, 21))
        self.setTimeLabel.setObjectName("setTimeLabel")
        self.HEXShowBox = QtWidgets.QCheckBox(self.centralwidget)
        self.HEXShowBox.setGeometry(QtCore.QRect(530, 305, 81, 21))
        self.HEXShowBox.setObjectName("HEXShowBox")
        self.portInfolabel = QtWidgets.QLabel(self.centralwidget)
        self.portInfolabel.setGeometry(QtCore.QRect(10, 420, 591, 21))
        self.portInfolabel.setObjectName("portInfolabel")
        self.showDataEdit = QtWidgets.QTextEdit(self.centralwidget)
        self.showDataEdit.setGeometry(QtCore.QRect(200, 10, 401, 281))
        self.showDataEdit.setObjectName("showDataEdit")
        self.saveWinBtn = QtWidgets.QPushButton(self.centralwidget)
        self.saveWinBtn.setGeometry(QtCore.QRect(320, 300, 93, 31))
        self.saveWinBtn.setObjectName("saveWinBtn")
        self.sendBytelabel = QtWidgets.QLabel(self.centralwidget)
        self.sendBytelabel.setGeometry(QtCore.QRect(10, 450, 51, 21))
        self.sendBytelabel.setObjectName("sendBytelabel")
        self.getBytelabel = QtWidgets.QLabel(self.centralwidget)
        self.getBytelabel.setGeometry(QtCore.QRect(70, 450, 51, 21))
        self.getBytelabel.setObjectName("getBytelabel")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 631, 23))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.openFileBtn.setText(_translate("MainWindow", "打开文件"))
        self.sendFileBtn.setText(_translate("MainWindow", "发送文件"))
        self.clearWinBtn.setText(_translate("MainWindow", "清除窗口"))
        self.portNamelabel.setText(_translate("MainWindow", "串口号"))
        self.sendDatalabel.setText(_translate("MainWindow", "字符串输入"))
        self.sendDataBtn.setText(_translate("MainWindow", "发送"))
        self.DTRBox.setText(_translate("MainWindow", "DTR"))
        self.RTSBox.setText(_translate("MainWindow", "RTS"))
        self.HEXSendBox.setText(_translate("MainWindow", "HEX发送"))
        self.openPortBtn.setText(_translate("MainWindow", "打开串口"))
        self.closePortBtn.setText(_translate("MainWindow", "关闭串口"))
        self.baudlabel.setText(_translate("MainWindow", "波特率"))
        self.bytelabel.setText(_translate("MainWindow", "数据位"))
        self.stopBitlabel.setText(_translate("MainWindow", "停止位"))
        self.paritylabel.setText(_translate("MainWindow", "校验位"))
        self.flowCtrlabel.setText(_translate("MainWindow", "流控制"))
        self.loopSendBox.setText(_translate("MainWindow", "定时发送"))
        self.setTimeLabel.setText(_translate("MainWindow", "ms/次"))
        self.HEXShowBox.setText(_translate("MainWindow", "HEX显示"))
        self.portInfolabel.setText(_translate("MainWindow", "串口信息"))
        self.saveWinBtn.setText(_translate("MainWindow", "保存窗口"))
        self.sendBytelabel.setText(_translate("MainWindow", "S:0"))
        self.getBytelabel.setText(_translate("MainWindow", "R:0"))

这个项目总共包含这四个文件,直接拷过去可能可以直接运行,也可能因为环境问题有一些bug。如果有什么问题欢迎在我的博客下留言,我会尽可能解答。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值