python3 + pyserial +pyqt5练习写串口助手(每个功能单独实现,按学习进度更新)

一、检测串口

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_mainWindow(object):
    def setupUi(self, mainWindow):
        mainWindow.setObjectName("mainWindow")
        mainWindow.resize(800, 600)
        mainWindow.setWindowTitle("")
        self.centralwidget = QtWidgets.QWidget(mainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(160, 130, 72, 15))
        self.label.setObjectName("label")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(240, 90, 93, 28))
        self.pushButton.setObjectName("pushButton")
        self.comboBox = QtWidgets.QComboBox(self.centralwidget)
        self.comboBox.setGeometry(QtCore.QRect(240, 127, 87, 22))
        self.comboBox.setObjectName("comboBox")
        self.label_2 = QtWidgets.QLabel(self.centralwidget)
        self.label_2.setGeometry(QtCore.QRect(160, 160, 180, 16))
        self.label_2.setObjectName("label_2")
        mainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(mainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 26))
        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
        self.label.setText(_translate("mainWindow", "当前串口:"))
        self.pushButton.setText(_translate("mainWindow", "检测串口"))
        self.label_2.setText(_translate("mainWindow", "无串口"))

class Port_Assitant(QtWidgets.QMainWindow,Ui_mainWindow):
    def __init__(self):
        super(Port_Assitant, self).__init__()
        self.setupUi(self)
        self.init()
        self.ser = serial.Serial()
    '''连接自定义功能'''
    def init(self):
        self.pushButton.clicked.connect(self.connect_port) #检测串口
    '''检测串口'''
    def port_check(self):
        self.port = {} #建一个字典存储所有串口的信息
        port_list = list(serial.tools.list_ports.comports()) #将所有串口存储到一个列表中
        if len(port_list) == 0:
            self.comboBox.addItem('无串口')
        else:
            for cur_port in port_list: #遍历所有串口
                self.port['{}'.format(cur_port[0])] = '{}'.format(cur_port[1]) #串口号:转串口硬件。
                self.comboBox.addItem(cur_port[0]) #加入下拉表
            self.label_2.setText(self.port[self.comboBox.currentText()]) #获取当前串口的硬件信息

# 程序入口,程序从此处启动PyQt设计的窗体
if __name__ == '__main__':
    import sys
    import serial
    import serial.tools.list_ports
    app = QtWidgets.QApplication(sys.argv)
    # MainWindow = QtWidgets.QMainWindow()     #创建窗体对象
    myshow = Port_Assitant()                   #创建PyQt设计的窗体对象
    # myshow.setupUi(MainWindow)               #调用PyQt窗体的方法对窗体对象进行初始化设置
    myshow.show()                              #显示窗体
    sys.exit(app.exec_())                      #程序关闭时退出程序

问题:在写完这个之后,运行是可以运行,但是点击检测串口时,下拉框却不显示串口名,经过我两个多小时的检查,发现是主函数里的

myshow.setupUi(MainWindow)

这个代码有问题,把他注释掉就可以了,上面的

MainWindow = QtWidgets.QMainWindow()

可注释可不注释,因为他是要与下面那行代码结合的。

如果有大牛知道为什么要把那行代码注释掉,希望能发一下评论,谢谢!

二、打开串口

在函数init(self)中加入(不要在意2和6不是连着的,当时忘了加关闭串口。。。)

        self.pushButton_2.clicked.connect(self.port_open)  #打开串口

        self.pushButton_6.clicked.connect(self.port_close) #关闭串口

在类Port_Assitant(QtWidgets.QMainWindow,Ui_mainWindow)中加入函数

    '''打开串口'''
    def port_open(self):
        self.ser.port = self.comboBox.currentText()            #串口号
        self.ser.baudrate = int(self.comboBox_2.currentText()) #波特率
        self.ser.bytesize = int(self.comboBox_3.currentText()) #数据位
        self.ser.parity = self.comboBox_4.currentText()        #校验位
        self.ser.stopbits = int(self.comboBox_5.currentText()) #停止位
        try:
            if self.ser.isOpen():
                return None
            self.ser.open()
            self.label_7.setText('串口已连接') #检查开没开串口
        except:
            QMessageBox.critical(self,'打开错误','请先检测串口!')
    '''关闭串口'''
    def port_close(self):
        self.ser.close()
        self.label_7.setText('串口未打开')

ui代码略,自己通过Qt Designer设计生成代码即可(之后也是,毕竟ui代码太多了。)

问题:写完代码开始运行时,点击检测串口,无报错,再点击打开串口,运行栏会出现

Process finished with exit code -1073740791

我是把网上下的代码助手程序关掉,再重新运行即可成功打开串口。

我网上搜了一下,推测我这种情况应该是当前串口已被调用,所以我把代码助手关掉后即可成功运行(我再次重试之后,的确如此,我把代码助手串口打开,自己写的就会报错了)。

三、发送与接收

在函数init()中加入

        self.pushButton_3.clicked.connect(self.send_data_clear) #发送清除

        self.pushButton_4.clicked.connect(self.receive_data_clear) #接收清除

        self.pushButton_5.clicked.connect(self.send_data) #发送数据

在类Port_Assitant(QtWidgets.QMainWindow,Ui_mainWindow)中加入函数

    '''发送与接收'''
    def send_data(self):
        if self.ser.isOpen():
            Input = self.textEdit.toPlainText()
            #非空字符串
            if Input != '':
                Input  = self.ser.write(Input.encode())
                Output = self.ser.read(Input).decode()
                self.textEdit_2.setPlainText(Output)
    '''发送清除'''
    def send_data_clear(self):
        self.textEdit.clear()
    '''接收清除'''
    def receive_data_clear(self):
        self.textEdit_2.clear()

即可简单地自发自收数据。

问题:无问题。

修改:

在此基础上加入了Ascii和Hex码。

    '''发送与接收'''
    def send_data(self):
        if self.ser.isOpen():
            Input = self.textEdit.toPlainText() #获取发送信息
            ###只读取最后一行###
            temp = ''
            for i in Input[::-1]:
                if i != '\n':
                    temp = i + temp
                else:
                    break
            Input = temp
            #################
            #非空字符串
            if Input != '':
                # 不变
                if self.radioButton.isChecked():
                    Input = self.ser.write(Input.encode())
                    Output = self.ser.read(Input).decode()
                    self.textEdit_2.append(Output) #追加文本
                # Hex
                elif self.radioButton_2.isChecked():
                    Input = Input.strip()
                    send_list = []
                    while Input != '': #不断截取数据前两个值
                        try:
                            num = int(Input[0:2],16)
                        except ValueError:
                            QMessageBox.critical(self, '格式错误', '请输入十六进制数据,以空格分开!') #报错
                            return None
                        Input = Input[2:].strip()
                        send_list.append(num)
                    Input = bytes(send_list) #转为bytes类型
                    Input = self.ser.write(Input)
                    data = self.ser.read(Input)
                    # Hex显示
                    Output = ''
                    for i in range(0, len(data)):
                        Output = Output + '{:02X}'.format(data[i]) + ' '
                    self.textEdit_2.append(Output)
                # Ascii
                elif self.radioButton_3.isChecked():
                    ###防止中间有很多空格####
                    Input = Input.strip()
                    send_list = []
                    for i in Input:
                        if i != ' ':
                            send_list.append(i)
                    Input = ''
                    for i in send_list:
                        Input += i + ' '
                    Input = Input[0:-1] #去掉最后的空格
                    #####################
                    Input = self.ser.write(Input.encode('ascii')) #ascii编码写入
                    Output = self.ser.read(Input).decode('ascii') #ascii解码读出
                    self.textEdit_2.append(Output)

四、打开摄像头

我单独写了一篇:https://blog.csdn.net/qq_52086693/article/details/123122742?spm=1001.2014.3001.5501

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值