基于PyQt5的串口助手开发

一、图形界面的设计

1、使用QtDesigner设计基本的图形界面,如下图

将文件命名为"ui_mainwindow.ui",保存到本地文件夹

设计配置文件界面,如下图所示,

将文件命名为“ui_settingdialog.ui”,保存到本地文件夹

2、使用PyUic将xx.ui文件转换为xx.py文件

二、图形界面的显示

1、新建一个settingdialog.py文件,在文件中创建一个基于QDialog的SettingDialog类
from PyQt5.QtWidgets import QDialog

from ui_settingdialog import Ui_Dialog

class SettingDialog(QDialog):
    def __init__(self,parent=None):
        super().__init__(parent)
        self.dialog = Ui_Dialog()
        self.dialog.setupUi(self)
 2、新建一个mainwindow.py文件,在文件中创建一个基于QMainWindow的MainWindow类
from PyQt5.QtWidgets import QMainWindow

from ui_mainwindow import Ui_MainWindow
from settingdialog import SettingDialog

class MainWindow(QMainWindow):
    def __init__(self,parent=None):
        super().__init__(parent)

        self.m_ui = Ui_MainWindow()
        self.m_ui.setupUi(self)

        self.m_setting = SettingDialog(self)#创建一个SettingDialog实例
        self.m_ui.actionConfigure.triggered.connect(self.m_setting.show)
3、新建一个main.py文件
import sys
from PyQt5.QtWidgets import QApplication
from mainwindow import MainWindow


if __name__ == "__main__":
    app = QApplication(sys.argv)
    win = MainWindow()
    win.show()
    sys.exit(app.exec())

运行main.py文件:

点击configure按键,显示Dialog界面

三、串口的操作

        1、串口参数设置
class SettingDialog(QDialog):
    def __init__(self,parent=None):
        super().__init__(parent)
        self.m_ui = Ui_Dialog()
        self.m_ui.setupUi(self)

        self.fill_ports_parameters()


    def fill_ports_parameters(self):
        self.m_ui.baudRateBox.addItem("9600", QSerialPort.Baud9600)
        self.m_ui.baudRateBox.addItem("19200", QSerialPort.Baud19200)
        self.m_ui.baudRateBox.addItem("38400", QSerialPort.Baud38400)
        self.m_ui.baudRateBox.addItem("115200", QSerialPort.Baud115200)
        self.m_ui.baudRateBox.addItem("Custom")
        self.m_ui.baudRateBox.setCurrentIndex(3)

        self.m_ui.dataBitsBox.addItem("5", QSerialPort.Data5)
        self.m_ui.dataBitsBox.addItem("6", QSerialPort.Data6)
        self.m_ui.dataBitsBox.addItem("7", QSerialPort.Data7)
        self.m_ui.dataBitsBox.addItem("8", QSerialPort.Data8)
        self.m_ui.dataBitsBox.setCurrentIndex(3)

        self.m_ui.parityBox.addItem("None", QSerialPort.NoParity)
        self.m_ui.parityBox.addItem("Even", QSerialPort.EvenParity)
        self.m_ui.parityBox.addItem("Odd", QSerialPort.OddParity)
        self.m_ui.parityBox.addItem("Mark", QSerialPort.MarkParity)
        self.m_ui.parityBox.addItem("Space", QSerialPort.SpaceParity)

        self.m_ui.stopBitsBox.addItem("1", QSerialPort.OneStop)
        if sys.platform == "win32":
            self.m_ui.stopBitsBox.addItem("1.5", QSerialPort.OneAndHalfStop)

        self.m_ui.stopBitsBox.addItem("2", QSerialPort.TwoStop)

        self.m_ui.flowControlBox.addItem("None", QSerialPort.NoFlowControl)
        self.m_ui.flowControlBox.addItem("RTS/CTS", QSerialPort.HardwareControl)
        self.m_ui.flowControlBox.addItem("XON/XOFF", QSerialPort.SoftwareControl)

运行效果:

        2、串口号扫描
class SettingDialog(QDialog):
    def __init__(self,parent=None):
        super().__init__(parent)
        self.m_ui = Ui_Dialog()
        self.m_ui.setupUi(self)

        self.fill_ports_parameters()
        self.full_port_info()

    def full_port_info(self):
        self.m_ui.serialPortInfoListBox.clear()
        for info in QSerialPortInfo.availablePorts():
            self.m_ui.serialPortInfoListBox.addItem(info.portName())

    def fill_ports_parameters(self):
        self.m_ui.baudRateBox.addItem("9600", QSerialPort.Baud9600)
        self.m_ui.baudRateBox.addItem("19200", QSerialPort.Baud19200)

运行效果:

3、点击Apply更新串口参数

创建一个Settings类初始化m_currentSettings值

class Settings():

    def __init__(self):
        self.name = ""
        self.baud_rate = 0
        self.string_baud_rate = ""
        self.data_bits = QSerialPort.Data8
        self.string_data_bits = ""
        self.parity = QSerialPort.NoParity
        self.string_parity = ""
        self.stop_bits =  QSerialPort.OneStop
        self.string_stop_bits = ""
        self.flow_control = QSerialPort.SoftwareControl
        self.string_flow_control = ""
        self.local_echo_enabled = False


class SettingDialog(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.m_ui = Ui_Dialog()
        self.m_ui.setupUi(self)
        self.m_currentSettings = Settings()  #m_currentSettings初始化

定义update_setting函数,将当前选择的参数传递给m_currentSettings

    def update_settings(self):
        self.m_currentSettings.name = self.m_ui.serialPortInfoListBox.currentText()

        self.m_currentSettings.baud_rate = self.m_ui.baudRateBox.currentData()
        self.m_currentSettings.string_baud_rate = f"{self.m_currentSettings.baud_rate}"

        self.m_currentSettings.data_bits = self.m_ui.dataBitsBox.currentData()
        self.m_currentSettings.string_data_bits = self.m_ui.dataBitsBox.currentText()

        self.m_currentSettings.parity = self.m_ui.parityBox.currentData()
        self.m_currentSettings.string_parity = self.m_ui.parityBox.currentText()

        self.m_currentSettings.stop_bits = self.m_ui.stopBitsBox.currentData()
        self.m_currentSettings.string_stop_bits = self.m_ui.stopBitsBox.currentText()

        self.m_currentSettings.flow_control = self.m_ui.flowControlBox.currentData()
        self.m_currentSettings.string_flow_control = self.m_ui.flowControlBox.currentText()

点击按键Apply调用update_settings()函数更新m_currentSettings值

class SettingDialog(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.m_ui = Ui_Dialog()
        self.m_ui.setupUi(self)
        self.m_currentSettings = Settings()  #m_currentSettings初始化

        self.m_ui.applyButton.clicked.connect(self.apply)

        self.fill_ports_parameters()
        self.full_port_info()

    def apply(self):
        self.update_settings()   #更新m_currentSettings值
        self.hide()              #隐藏Dialog
4、使用当前参数打开/关闭串口
from PyQt5.QtWidgets import QMainWindow, QMessageBox
from ui_mainwindow import Ui_MainWindow
from settingdialog import SettingDialog
from PyQt5.QtSerialPort import QSerialPort
from PyQt5.QtCore import QIODevice,Qt

class MainWindow(QMainWindow):
    def __init__(self,parent=None):
        super().__init__(parent)

        self.m_ui = Ui_MainWindow()
        self.m_ui.setupUi(self)
        self.m_serial = QSerialPort(self)
        self.m_settings = SettingDialog(self)#创建一个SettingDialog实例

        self.m_ui.actionConnect.setEnabled(True)
        self.m_ui.actionDisconnect.setEnabled(False)
        self.m_ui.actionQuit.setEnabled(True)
        self.m_ui.actionConfigure.setEnabled(True)

        self.m_ui.actionConfigure.triggered.connect(self.m_settings.show)
        self.m_ui.actionConnect.triggered.connect(self.open_serial_port)
        self.m_ui.actionDisconnect.triggered.connect(self.close_serial_port)

    def open_serial_port(self):
        s = self.m_settings.setting()
        self.m_serial.setPortName(s.name)
        self.m_serial.setBaudRate(s.baud_rate)
        self.m_serial.setParity(s.parity)
        self.m_serial.setDataBits(s.data_bits)
        self.m_serial.setStopBits(s.stop_bits)
        self.m_serial.setFlowControl(s.flow_control)
        try:
            if self.m_serial.open(QIODevice.ReadWrite):
                self.m_ui.actionConnect.setEnabled(False)
                self.m_ui.actionDisconnect.setEnabled(True)
                self.m_ui.actionConfigure.setEnabled(False)
                print("open success")
            else:
                QMessageBox.critical(self, "Error", self.m_serial.errorString())
                self.show_status_message("Open error")
                print("open failed")
        except:
            print("can not open this serial")

    def close_serial_port(self):
        print("close_serial_port")
        if self.m_serial.isOpen():
            self.m_serial.close()
        self.m_ui.actionConnect.setEnabled(True)
        self.m_ui.actionDisconnect.setEnabled(False)
        self.m_ui.actionConfigure.setEnabled(True)

运行效果:

四、串口数据显示

在MainWindow类中创建一个QPlainTextEdit的实例,用来显示接收到的串口数据

class MainWindow(QMainWindow):
    def __init__(self,parent=None):
        super().__init__(parent)
        。
        。
        。
        self.m_textEdit = QPlainTextEdit(self) #用来显示接收到的串口数据
        self.setCentralWidget(self.m_textEdit) #居中显示

定义read_data()函数,用来读取串口数据,并将串口数据显示在m_textEdit中

    def read_data(self):
        data = self.m_serial.readAll().data().decode("utf8")
        self.m_textEdit.insertPlainText(data)
        bar = self.m_textEdit.verticalScrollBar()  #滚动刷新
        bar.setValue(bar.maximum())

当接收到串口数据时,调用read_data()函数

class MainWindow(QMainWindow):
    def __init__(self,parent=None):
        super().__init__(parent)
        。
        。
        。
        self.m_serial.readyRead.connect(self.read_data)


    def read_data(self):
        data = self.m_serial.readAll().data().decode("utf8")
        self.m_textEdit.insertPlainText(data)
        bar = self.m_textEdit.verticalScrollBar()
        bar.setValue(bar.maximum())

运行效果:

背景颜色、字体、大小等设置

class MainWindow(QMainWindow):
    def __init__(self,parent=None):
        super().__init__(parent)
        。
        。
        。
        self.m_serial.readyRead.connect(self.read_data)

        p = self.palette()
        p.setColor(QPalette.Base, Qt.black)  # 设置背景颜色
        p.setColor(QPalette.Text, Qt.white)  # 设置字体颜色
        self.setPalette(p)

        font = QFont("Monaco", 11)  # 设置字体,大小
        self.m_textEdit.setFont(font)

运行效果:

  • 1
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值