pyqt5实现串口工具

news2024/9/22 19:31:41

使用pyqt5做一个串口工具

  • 一、设计界面
  • 二、功能代码实现

一、设计界面

界面使用qtdesigner设计,然后在转成Python代码,以下是转好后的代码
在这里插入图片描述
untitled_serial.py

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'untitled_serial.ui'
#
# Created by: PyQt5 UI code generator 5.15.10
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        MainWindow.setStyleSheet("\"background-color: red; border-radius: 50%;\"")
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(310, 20, 141, 61))
        font = QtGui.QFont()
        font.setFamily("Algerian")
        font.setPointSize(24)
        self.label.setFont(font)
        self.label.setObjectName("label")
        self.comboBox = QtWidgets.QComboBox(self.centralwidget)
        self.comboBox.setGeometry(QtCore.QRect(360, 90, 91, 21))
        self.comboBox.setObjectName("comboBox")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.label_2 = QtWidgets.QLabel(self.centralwidget)
        self.label_2.setGeometry(QtCore.QRect(280, 90, 61, 20))
        font = QtGui.QFont()
        font.setFamily("Algerian")
        font.setPointSize(12)
        self.label_2.setFont(font)
        self.label_2.setObjectName("label_2")
        self.label_3 = QtWidgets.QLabel(self.centralwidget)
        self.label_3.setGeometry(QtCore.QRect(280, 130, 61, 21))
        font = QtGui.QFont()
        font.setFamily("Algerian")
        font.setPointSize(12)
        self.label_3.setFont(font)
        self.label_3.setObjectName("label_3")
        self.comboBox_2 = QtWidgets.QComboBox(self.centralwidget)
        self.comboBox_2.setGeometry(QtCore.QRect(360, 130, 91, 21))
        self.comboBox_2.setObjectName("comboBox_2")
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setGeometry(QtCore.QRect(252, 480, 151, 21))
        self.lineEdit.setObjectName("lineEdit")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(420, 480, 75, 23))
        self.pushButton.setObjectName("pushButton")
        self.pushButton_open_serial = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_open_serial.setGeometry(QtCore.QRect(300, 180, 75, 23))
        self.pushButton_open_serial.setObjectName("pushButton_open_serial")
        self.pushButton_close_serial = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_close_serial.setGeometry(QtCore.QRect(390, 180, 75, 23))
        self.pushButton_close_serial.setObjectName("pushButton_close_serial")
        self.label_view = QtWidgets.QLabel(self.centralwidget)
        self.label_view.setGeometry(QtCore.QRect(270, 180, 21, 21))
        self.label_view.setAutoFillBackground(False)
        self.label_view.setStyleSheet("background-color: rgb(0, 0, 0);\n"
"")
        self.label_view.setText("")
        self.label_view.setObjectName("label_view")
        self.listWidget = QtWidgets.QListWidget(self.centralwidget)
        self.listWidget.setGeometry(QtCore.QRect(250, 250, 256, 192))
        self.listWidget.setObjectName("listWidget")
        self.label_5 = QtWidgets.QLabel(self.centralwidget)
        self.label_5.setGeometry(QtCore.QRect(250, 220, 81, 20))
        self.label_5.setObjectName("label_5")
        self.label_4 = QtWidgets.QLabel(self.centralwidget)
        self.label_4.setGeometry(QtCore.QRect(260, 450, 81, 21))
        self.label_4.setObjectName("label_4")
        self.checkBox = QtWidgets.QCheckBox(self.centralwidget)
        self.checkBox.setGeometry(QtCore.QRect(340, 220, 131, 21))
        self.checkBox.setObjectName("checkBox")
        self.checkBox_2 = QtWidgets.QCheckBox(self.centralwidget)
        self.checkBox_2.setGeometry(QtCore.QRect(350, 450, 121, 21))
        self.checkBox_2.setObjectName("checkBox_2")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 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", "串口工具"))
        self.label.setText(_translate("MainWindow", "串口工具"))
        self.comboBox.setItemText(0, _translate("MainWindow", "115200"))
        self.comboBox.setItemText(1, _translate("MainWindow", "9600"))
        self.comboBox.setItemText(2, _translate("MainWindow", "38400"))
        self.label_2.setText(_translate("MainWindow", "波特率:"))
        self.label_3.setText(_translate("MainWindow", "串口号:"))
        self.pushButton.setText(_translate("MainWindow", "发送"))
        self.pushButton_open_serial.setText(_translate("MainWindow", "打开串口"))
        self.pushButton_close_serial.setText(_translate("MainWindow", "关闭串口"))
        self.label_5.setText(_translate("MainWindow", "数据显示格式:"))
        self.label_4.setText(_translate("MainWindow", "数据发送格式:"))
        self.checkBox.setText(_translate("MainWindow", "ASCII(默认)/HEX"))
        self.checkBox_2.setText(_translate("MainWindow", "ASCII(默认)/HEX"))

二、功能代码实现

上面设计好了界面项目就要对串口功能实现,界面和功能代码我这边是分开文件来写,如果写成一个文件每次在界面转python代码过程中那些数据就会丢失,分开写就不会存在这样的烦恼。
untitled_seria_action.py

import untitled_serial
import serial
import serial.tools.list_ports
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QFileDialog, QMessageBox, QListWidget, QListWidgetItem,QListView


from PyQt5.QtCore import QThread, pyqtSignal  #添加线程头文件
from datetime import datetime
class SerialThread(QThread): #创建一个串口线程类
    ser=''
    stop_event = False
    port=""
    baudrate=""
    choose_view = False  # 判断是选择hex显示字符串显示
    choose_send =False #判断是选择hex发送还是字符串发送
    data_received = pyqtSignal(str)#创建线程传输字符串数据
    def __init__(self, port, baudrate):
        super().__init__()
        self.port = port
        self.baudrate = baudrate
        self.serial_start(self.port,self.baudrate)

    def serial_start(self, port, baudrate):
        print("串口已经运行")
        self._stop_event = False
        self.ser = serial.Serial(port, baudrate, timeout=1)

    def run(self):
        while not self._stop_event:
            if self.ser.in_waiting:
                if self.choose_view:
                    dataReady = self.ser.read_all().hex()
                else:
                    #dataReady=self.ser.readline().decode('utf-8')
                    dataReady = self.ser.read_all().decode('utf-8')
                print(dataReady)
                # data = self.ser.readline().decode('utf-8').strip()
                self.data_received.emit(dataReady)
    def write(self, data):
        if self.choose_send:
            if len(data)%2==1:#判断输入的数据是否是1位
                data='0'+data
            self.ser.write(bytes.fromhex(data))#输入16进制
        else:
            self.ser.write(data.encode('utf-8'))#输入asicc
    def serial_stop(self):
        self._stop_event = True
        self.ser.close()
    def state(self): #状态函数,判断串口是否打开
        if not self._stop_event:
            return True
        else:
            return False

class serialaction(untitled_serial.Ui_MainWindow,QMainWindow):
    serial_thread=""
    def __init__(self):
        super(untitled_serial.Ui_MainWindow,self).__init__()
        self.setupUi(self)

        ports = serial.tools.list_ports.comports()#获取串口号
        for port in ports: #通过for循环批量打印出串口号
            item =port.device
            self.comboBox_2.addItem(item) #将串口号添加到comboBox控件里面
        self.pushButton_open_serial.clicked.connect(self.open_serial)#创建槽函数
        self.pushButton.clicked.connect(self.send_data)
        self.bote_value = self.comboBox.currentText()  # 获取选的串口波特率
        self.combo_value = self.comboBox_2.currentText()  # 获取选的串口号

        self.pushButton_close_serial.clicked.connect(self.serial_close) # 将线程信号连接到槽函数

        self.checkBox.clicked.connect(self.check_choose_view)
        self.checkBox_2.clicked.connect(self.check_choose_send)  # 判断是否选择hex发送
    def open_serial(self): #打开串口
        self.serial_thread = SerialThread(self.combo_value, self.bote_value)  # 创建串口线程
        self.serial_thread.data_received.connect(self.display_data)  # 将线程信号连接到槽函数
        self.label_view.setStyleSheet("background-color: rgb(0, 255, 0);")
        if self.serial_thread._stop_event == True:  # 判断串口是否打开
            self.bote_value = self.comboBox.currentText()  # 获取选的串口波特率
            self.combo_value = self.comboBox_2.currentText()  # 获取选的串口号
            self.serial_thread.serial_start( self.combo_value,self.bote_value)#再次启动串口
        self.serial_thread.start()#启动线程

        self.listWidget.addItem("串口打开\n")#设置数据显示在界面
        self.listWidget.setCurrentRow(self.listWidget.count() - 1)#设置显示最后一行

    def serial_close(self):
        self.serial_thread.serial_stop()
        self.label_view.setStyleSheet("background-color: rgb(0, 0, 0);")

        self.listWidget.addItem("串口关闭\n")#设置数据显示在界面
        self.listWidget.setCurrentRow(self.listWidget.count() - 1)#设置显示最后一行

    def display_data(self,data):
        current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')  # 获取系统时间
        self.listWidget.addItem(current_time+"\n"+data+"\n")#设置数据显示在界面
        self.listWidget.setCurrentRow(self.listWidget.count() - 1)#设置显示最后一行

    def send_data(self):
        if (self.serial_thread._stop_event):#判断串口是否打开,如果未打开给与提示
            QMessageBox.information(self, "提示", "请先打开串口")
        else:
            data = self.lineEdit.text()
            data = data + '\r\n'
            self.serial_thread.write(data)
            # self.lineEdit.clear()
    def check_choose_view(self): #判断复选框是否选中
        if self.checkBox.isChecked():#判断那种格式显示
            self.serial_thread.choose_view = True
        else:
            self.serial_thread.choose_view = False

    def check_choose_send(self):#判断那种格式输入
        if self.checkBox_2.isChecked():
            self.serial_thread.choose_send = True
        else:
            self.serial_thread.choose_send1 = False


# 主程序入口
if __name__ == '__main__':
    # 这里是界面的入口,在这里需要定义QApplication对象,之后界面跳转时不用再重新定义,只需要调用show()函数即可
    app = QApplication(sys.argv)
    # 实例化
    window = serialaction()
    # 显示
    window.show()

    sys.exit(app.exec_())

下面是实现效果
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1237689.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【HarmonyOS】获取备案需要的公钥和MD5签名问题

【关键字】 HarmonyOS、公钥、MD5签名 【问题描述】 有cp反馈Harmony App如何获取备案需要的公钥和MD5签名。 【解决方案】 1、获取备案需要的公钥: 1)用记事本打开签名对应.cer文件 2)里面的内容粘贴到一个可以查看证书的网站上面&…

【广州华锐互动】VR防溺水安全内容体验提高群众防溺水意识

在全球各地,溺水是导致儿童和青少年死亡的主要原因之一。据世界卫生组织的统计,全球每年有超过36万人因溺水而死亡,其中大部分是儿童和青少年。因此,提供有效的防溺水教育和培训至关重要。随着科技的发展,虚拟现实&…

C++_String增删查改模拟实现

C_String增删查改模拟实现 前言一、string默认构造、析构函数、拷贝构造、赋值重载1.1 默认构造1.2 析构函数1.3 拷贝构造1.4 赋值重载 二、迭代器和范围for三、元素相关:operator[ ]四、容量相关:size、resize、capacity、reserve4.1 size、capacity4.2…

【Redis篇】简述Redis | 详解Redis命令

文章目录 🎍什么是Redis🎍Redis特点🎍Redis应用场景🍔Windows安装Redis⭐启动Redis 🌺Redis数据类型🌺Redis常用命令⭐字符串string操作命令⭐哈希hash操作命令⭐列表list操作命令⭐集合set操作命令⭐有序集…

在Ubuntu18.04安装适合jdk8的eclipse

直接在Ubuntu软件那里下载的eclipse不能用,下载后启动会报错:Eclipse An error has occurred. See the log file/home/hadoop/.eclipse/ org.eclipse.platform_3.8_155965261/ configuration/1700567835954.log 上网搜索方法,按教程说的修改e…

华为认证 | HCIE考证流程详解!

HCIE(Huawei Certified ICT Expert,华为认证ICT专家)是华为认证体系中最高级别的ICT技术认证,旨在打造高含金量的专家级认证,为技术融合背景下的ICT产业提供新的能力标准,以实现华为认证引领ICT行业技术认证…

斯坦福NLP课程来了

生成式AI,尤其是以ChatGPT为首的大语言模型正在改变人们的生活方式,我想一定有小伙伴想加入NLP这个行列。 微软重磅发布4个适合初学者的机器学习资料 我在前一篇文章中分享了微软人工智能初学者课程,其中的【生成式AI】非常适合初学者&…

系列六、ThreadLocal内存泄漏案例

一、内存泄漏 vs 内存溢出 内存泄漏:内存泄漏是指程序中已经动态分配的堆内存由于某种原因程序未释放或者无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至导致系统崩溃等严重后果,内存泄漏最终 会导致内…

2023年中国高压驱动芯片分类、市场规模及发展趋势分析[图]

高压驱动芯片是一种能在高压环境下工作的集成电路,主要用于控制和驱动各种功率器件,如继电器、电磁阀、电机、变频器等。高压驱动芯片根据其输出电流的大小和形式可分为两类恒流型和开关型。 高压驱动芯片分类 资料来源:共研产业咨询&#x…

CorelDRAW2024有哪些新功能?如何下载

作为一个广告设计者怎么能不会一两款专业设计软件,Adobe公司的PS、AI和Corel公司的CorelDRAW都是常用的图片处理软件,也是市场上同类设计软件中的翘楚。针对不同的设计任务选择不同的设计软件,才能提高工作效率,事半功倍。 Corel…

七个步骤 从零到servlet第一个hello

目录 Tomcat安装 Servlet 1.引入项目 2.引入依赖 3.创建目录 1.创建 webapp 目录 2.创建 web.xml 3.编写 web.xml 4.编写代码 5.打包程序 6.部署程序 7.验证程序 Smart Tomcat Tomcat安装 在动漫世界,我们有汤姆猫 在Java世界,同样也有一个…

精彩预告 | OpenHarmony即将亮相MTSC 2023

MTSC 2023 第12届中国互联网测试开发大会(深圳站)即将于2023年11月25日,在深圳登喜路国际大酒店举办,大会将以“1个主会场4个平行分会场”的形式呈现,聚集一众顶尖技术专家和行业领袖,围绕如今备受关注的行…

redis之主从复制和哨兵模式

(一)redis的性能管理 1、redis的数据缓存在内存中 2、查看redis的性能:info memory(重点) used_memory:904192(单位字节) redis中数据占用的内存 used_memory_rss:10522624 redis向操作系统…

锯木棍

题目描述 有一根粗细均匀长度为 L 的木棍,先用红颜色刻度线将它 m 等分,再用蓝色刻度线将 其 n 等分( m>n ),然后按所有刻度线将该木棍锯成小段,计算并输出长度最长的木棍的长度和根数。 输入格式…

(内部资料)收下这几个人工智能学习秘籍!

秘籍一:练好基本功 学习基础知识:人工智能涉及多个学科领域,包括数学、计算机科学、统计学等。因此,学习基础知识是非常重要的。您可以通过学习线性代数、概率论和微积分等数学基础知识,以及掌握Python编程语言和常用…

Linux学习笔记-Ubuntu下使用Crontab设置定时任务

文章目录 一、概述二、基于crontab的设置2.1 基本命令说明2.2 使用-e指令编辑命令2.2.1 进入编辑模式2.2.2 指令信息格式2.2.4 开启日志1) 修改rsyslog配置文件2) 重启rsyslog3) 查看日志 2.2.3 设置后之后重启服务 三、示例3.1 每隔一分钟往文件中日期3.2 使用-l查看任务列表3…

微软重磅发布4个适合初学者的机器学习资料

自媒体火起来后,很多科技大佬都开始写博客,录视频了,大佬一入行,整个行业卷上天,像我这样的也只能走资源整合之路了,不过这样也好,科技进步,人类发展需要他们。 除了个人&#xff0…

深度学习常见激活函数:ReLU,sigmoid,Tanh,softmax,Leaky ReLU,PReLU,ELU整理集合,应用场景

文章目录 1、ReLU 函数(隐藏层中是一个常用的默认选择)1.1 优点1.2 缺点 2、sigmoid 函数2.1 优点2.2 缺点 3、Tanh 函数3.1 优点3.2 缺点 4、softmax 函数(多分类任务最后一层都会使用)5、Leaky ReLU 函数5.1 优点5.2 缺点 6、PR…

KDE 项目发布了 KDE Gear 23.08.3

导读KDE 项目发布了 KDE Gear 23.08.3,作为最新的 KDE Gear 23.08 开源集合的第三次维护更新,该集合包含了用于 KDE Plasma 桌面环境和其他平台的 KDE 应用程序。 KDE Gear 23.08.3 是在 KDE Gear 23.08.2 大约一个月之后发布的,包含了更多对…

Maven中常用命令以及idea中使用maven指南

文章目录 Maven 常用命令compiletestcleanpackageinstallMaven 指令的生命周期maven 的概念模型 idea 开发maven 项目idea 的maven 配置idea 中创建一个maven 的web 工程在pom.xml 文件添加坐标坐标的来源方式依赖范围编写servlet maven 工程运行调试 Maven 常用命令 compile …