【PyQt】PyQt5进阶——串口上位机及实时数据显示

news2024/9/21 20:48:51

文章目录

  • 0 前期教程
  • 1 前言
  • 2 串口部分——QtSerialPort
  • 3 绘图部分
    • 3.1 QCustomPlot
    • 3.2 QtChart
    • 3.3 QWT
    • 3.4 Qt Designer中如何使用
  • 参考链接

0 前期教程

  • 【Python】PyQt5入门

1 前言

  最近在用PyQt做一个串口上位机,需要串口通信和实时显示曲线。这里简单记录一些关键点。

2 串口部分——QtSerialPort

  这个是在安装PyQt5时自动安装的组件,使用方法比较简单,主要是两个模块:QSerialPort, QSerialPortInfo

# 导入包
from PyQt5.QtSerialPort import QSerialPort, QSerialPortInfo

#获取当前的所有串口,得到一个列表
portlist = QSerialPortInfo.availablePorts()
#获取串口的名称和描述
l = [x.portName()+x.description() for x in self.portlist] 
#建立一个串口,里面的参数可以填串口名或者就是串口类
ser = QSerialPort()
#接收数据对应调用的函数
ser.readyRead.connect(recv_data)

#设置串口
def init_port(self, port:QSerialPort):
	port.setBaudRate(self.baud)
	port.setDataBits(QSerialPort.DataBits.Data8)
	port.setParity(QSerialPort.Parity.NoParity)
	port.setStopBits(QSerialPort.StopBits.OneStop)
	port.readyRead.connect(recv_data)

#数据接收
data = ser.readAll().data() #得到的是字节字符串

  以上就是串口部分的代码,比较简单,利用代码提示基本没有什么问题。

关于字节字符串的处理可以看一下这篇文章

  • 【学习笔记】字节数据和字节字符串(b“ “)那些事

3 绘图部分

  经过调研,发现在Qt当中绘制函数曲线,常用的有3个包,分别是QCustomPlot , QWTQtChart,其中前两者都是第三方包,后者是Qt官方做的,不过三者都兼容PyQt5就是了

3.1 QCustomPlot

  QCustomPlot目前在pypi上好像有好几个版本

在这里插入图片描述

除此之外,如果直接运行pip install QCustomPlot2也是可以安装的,而且用着感觉和QCustomPlot-PyQt5没什么区别,所以也不知道啥有这么多的版本。

  不过这个包有一个最大的问题,那就是它对Python的支持不够好。网上有很多关于这个包在C环境下的使用,但是Python环境下却不支持代码提示,安装的包是一个编译过的pyd文件。

  以下是一个例子

import sys
import math
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPen, QBrush, QColor
from PyQt5.QtWidgets import QApplication, QMainWindow

from QCustomPlot2 import QCustomPlot, QCP
#以上QCustomPlot2完全可以直接换成QCustomPlot-PyQt5

app = QApplication(sys.argv)
window = QMainWindow()
window.resize(800, 600)

customPlot = QCustomPlot()
window.setCentralWidget(customPlot)

graph0 = customPlot.addGraph()
graph0.setPen(QPen(Qt.blue))
graph0.setBrush(QBrush(QColor(0, 0, 255, 20)))

graph1 = customPlot.addGraph()
graph1.setPen(QPen(Qt.red))

x, y0, y1 = [], [], []
for i in range (251):
    x.append(i)
    y0.append(math.exp(-i/150.0)*math.cos(i/10.0))  # exponentially decaying cosine
    y1.append(math.exp(-i/150.0))                   # exponential envelope

graph0.setData(x, y0)
graph1.setData(x, y1) #除setData外,还有addData函数,即添加一个点

customPlot.rescaleAxes()
customPlot.setInteraction(QCP.iRangeDrag)
customPlot.setInteraction(QCP.iRangeZoom)
customPlot.setInteraction(QCP.iSelectPlottables)

window.show()
sys.exit(app.exec_())

以下是在类中的使用参考:

def initPlot(self):
    self.ui.widget

    self.ui.widget.setInteractions(QCP.iRangeDrag | QCP.iRangeZoom | QCP.iSelectAxes | QCP.iSelectLegend | QCP.iSelectPlottables)
    # self.ui.widget.axisRect().setRangeZoomAxes(, self.ui.widget.yAxis)
    self.ui.widget.xAxis.setLabel("t")
    self.ui.widget.yAxis.setLabel("accel")
    self.ui.widget.legend.setVisible(True)
    self.ui.widget.yAxis.setRange(-2,2)

    self.ui.widget.axisRect().insetLayout().setInsetAlignment(0, Qt.AlignLeft|Qt.AlignTop)

    self.ui.widget.addGraph()#添加第1条曲线
    self.ui.widget.graph(0).setName("x")#曲线名称
    self.ui.widget.graph(0).setPen(QPen(Qt.red)) # line1 color red for second graph

    self.ui.widget.addGraph()#添加第2条曲线
    self.ui.widget.graph(1).setName("y")#曲线名称
    self.ui.widget.graph(1).setPen(QPen(Qt.blue)) # line1 color red for second graph

    self.ui.widget.addGraph()#添加第3条曲线
    self.ui.widget.graph(2).setName("z")#曲线名称
    self.ui.widget.graph(2).setPen(QPen(Qt.green)) # line1 color red for second graph

    self.ui.widget.addGraph()#添加第4条曲线
    self.ui.widget.graph(3).setName("norm")#曲线名称
    self.ui.widget.graph(3).setPen(QPen(Qt.cyan)) # line1 color red for second graph

    self.key_init = QDateTime.currentDateTime().toMSecsSinceEpoch()/1000

def fresh(self, x=0, y=0, z=0, norm=0):
    key = QDateTime.currentDateTime().toMSecsSinceEpoch()/1000 - self.key_init
    self.ui.widget.graph(0).addData(key, x)
    self.ui.widget.graph(1).addData(key, y)
    self.ui.widget.graph(2).addData(key, z)
    self.ui.widget.graph(3).addData(key, norm)
    self.ui.widget.rescaleAxes()

    # self.ui.widget.xAxis.setRange(self.x, 8, Qt.AlignRight)
    self.ui.widget.replot()

3.2 QtChart

  使用前先安装:pip install PyQtChart,在使用这个包时,要注意其基本的逻辑。显示的类为QChartView, 但是QChartView需要关联一个QChart,而每个QChart可以包含一个或多个series,即一条或多条曲线,当然series类型有很多,这个和曲线计算方式和想要绘制图形的类型有关。看个例子。

import sys
from PyQt5.QtGui import QPainter
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout
from PyQt5.QtChart import QLineSeries, QChart, QChartView
def create_chart():
    # 创建折线图的数据
    series = QLineSeries()
    series.append(0, 0)
    series.append(1, 1)
    series.append(2, 2)
    series.append(3, 3)
    chart = QChart()
    chart.addSeries(series)
    chart.setTitle('Chart Example') # 设置图表标题
    chart.setAnimationOptions(QChart.SeriesAnimations) # 设置动画效果
    return chart
class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setWindowTitle('QtChart Example')
        chart_view = QChartView(create_chart())

        chart_view.setRenderHint(QPainter.Antialiasing) # 设置渲染方式
        self.setCentralWidget(chart_view)
if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

3.3 QWT

  这个没有用过,但是感觉还行,也有代码提示,安装方法:

# 一定要安装这个包,否则无法使用
pip install pyqt5-tools
# 再安装对应的包
pip install PythonQwt

这里给一个pypi官网提供的例子:

from qtpy import QtWidgets as QW
import qwt
import numpy as np

app = QW.QApplication([])
x = np.linspace(-10, 10, 500)
plot = qwt.QwtPlot("Trigonometric functions")
plot.insertLegend(qwt.QwtLegend(), qwt.QwtPlot.BottomLegend)
qwt.QwtPlotCurve.make(x, np.cos(x), "Cosinus", plot, linecolor="red", antialiased=True)
qwt.QwtPlotCurve.make(x, np.sin(x), "Sinus", plot, linecolor="blue", antialiased=True)
plot.resize(600, 300)
plot.show()
app.exec_()

3.4 Qt Designer中如何使用

  在上面的前期教程当中,有提到PyQt常用的开发方式,就是在Qt Designer中设计ui,然后转换成py文件,再另写一个py文件进行界面的显示和处理。那这些曲线怎么在Qt Designer中设计呢?

  在需要显示的位置放置一个Widget控件:

在这里插入图片描述

然后右键该控件,选择“提升为”

在这里插入图片描述

在这里插入图片描述

这里主要是填两个空,即提升的类名称和头文件,由于Python当中没有头文件,实际填的是模块名。即保证结构是from B import A,其中A应该是一个显示的类,具体应该填什么根据使用的包决定。比如如果使用的是QtChart,那么应该是from PyQt5.QtChart import QChartView

参考链接

  • PyQt5 QSerialPort子线程操作
  • Python3+PyQt5+QtChart 实现简单的实时更新曲线图
  • QChart的简单使用
  • Qwt、QChart、QCustomPlot使用
  • PyQtChart

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

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

相关文章

【已解决】最简单便捷的方法将多html合并为pdf

一、单页面转pdf 可以使用pdf24,https://tools.pdf24.org/zh/webpage-to-pdf。 也可以直接打印 二、多页面转pdf(wkhtmltopdf方案) 1、安装配置pdfkit:[https://blog.csdn.net/xc_zhou/article/details/80952168(https://blog.…

Charles安装及使用教程

一. 简介及安装 一、charles的使用 1.1 charles的说明 Charles其实是一款代理服务器,通过过将自己设置成系统(电脑或者浏览器)的网络访问代理服务器,然后截取请求和请求结果达到分析抓包的目的。该软件是用Java写的&#xff0…

Nestjs全网最佳翻译-概况-管道-Pipes

管道 带上装饰器 Injectable() 并实现了 PipeTransform 接口的类,就是管道。 管道有 2 个典型的应用场景: 数值转换:将输入的参数转换成目标类型,例如,string to number。 数值校验:对输入的参数进行校验…

cocos creator v3.6版本使用Intersection2D模块的circleCircle方法

在cocos creator v3版本中Intersection2D模块的circleCircle方法可以用来检测两个圆形是否相交 该方法可以实现的功能有: cocos creator吸铁石实现、cocos creator物体在固定位置吸附、cocos creator物体吸附效果、cocos creator吸铁石实现、cocos creator两个物体时…

统计软件与数据分析Lesson9----爬虫解析库Beautiful Soup

统计软件与数据分析Lesson9----爬虫解析库Beautiful Soup知识点总结 1.requests 模块1.1 查看requests功能函数1.2 发送请求1.3 传递URL参数1.4 获取响应内容 2.Beautiful Soup模块2.1 解析器2.2 对象类型2.2.1 Beautiful Soup2.2.2 标签Tag2.2.3 可遍历的字符串NavigableStrin…

Java——包含min函数的栈

题目链接 牛客在线oj题——包含min函数的栈 题目描述 定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的 min 函数,输入操作时保证 pop、top 和 min 函数操作时,栈中一定有元素。 此栈包含的方法有: push(va…

SRv6实践项目(六):控制面完成链路和主机的发现

在本次实验中,我们需要利用ONOS完成对数据面的控制 1.使能packet的IO功能,验证链路发现 main.p4提供了和P4Runtime的通信的消息的定义格式,分别是PacketIn和PacketOut,他们都被加上了一个注解,表示这是一个控制器交互…

c++篇---缺省参数

文章目录 一、缺省参数概念二、缺省参数实例三、缺省参数声明和定义四、全缺省和半缺省 一、缺省参数概念 缺省参数 在调用该函数时,如果实参没有指定传内容,那么在函数中用形参时,就采用为函数参数指定的这个缺省值 但是如果在调用该函数时…

【Qt 实现一个画板,基于QWidget,可以绘制直线和矩形】

【Qt 实现一个画板,基于QWidget,可以绘制直线和矩形】 简介效果展示源码mainwindow.hmainwindow.cpppainterwidget.hpainterwidget.cppshape.h (管理)line.hline.cpprect.hrect.cpp 结 🙉🙉更多内容 点击:Q…

力扣sql中等篇练习(七)

力扣sql中等篇练习(七) 1 查询活跃业务 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 1.2 示例sql语句 # Write your MySQL query statement below # 先求出所有业务的平均发生次数 SELECT t2.business_id FROM (SELECT e.*,IF(e.occurences>t1.A_NUM,1,0) tota…

【C++】vector的简化模拟实现

文章目录 1. 主要结构2. 默认成员函数3. 迭代器4. 容量相关1. size和capacity2. reserve3. resize 5. 数据访问6. 数据修改1. push_back2.pop_back3. insert4.erase5.swap6.clear 1. 主要结构 参照SGI版本的vector实现,使用三个指针来维护这样一段内存空间 templa…

ACL访问控制列表简介和配置演示

一.ACL功能和特点 1.功能 2.特点 二.ACL种类 1.基础ACL: 2.增强ACL: 三.配置演示 1.基础ACL: 2.增强ACL: 一.ACL功能和特点 1.功能 对感兴趣的路由 (控制层面)进行设置策略 对感兴趣的流量 (数据层面)进行设置策略 2.…

Activity启动模式的生命周期

四种启动模式 1.standard android:launchMode"standard" 默认的标准启动模式,每次启动当前Activity,任务栈中都添加一个当前Activity的实例。按返回键时,表现出退出多个当前Activity的现象。 MainActivityOne和MainActivityTwo都…

DPText-DETR原理及源码解读

一、原理 发展脉络:DETR是FACEBOOK基于transformer做检测开山之作,Deformable DETR加速收敛并对小目标改进,TESTR实现了端到端的文本检测识别,DPText-DETR做了精度更高的文字检测。 DETR 2020 FACEBOOK: 原理 https://…

c/c++:函数的作用,分类,随机数,函数定义,调用,申明,exit()函数,多文件编程,防止头文件重复

c/c:函数的作用,分类,随机数,函数定义,调用,申明,exit()函数,多文件编程,防止头文件重复 2022找工作是学历、能力和运气的超强结合体,遇到寒冬,大…

Spring启动及Bean实例化过程来看经典扩展接口

目录 一、Spring启动及Bean实例化过程 二、分析其对应经典扩展接口 三、对开发的指导意义 备注:以下总结只是一些基本的总结思路,具体每个扩展接口的应用后续进行分析总结。 一、Spring启动及Bean实例化过程 Spring启动及Bean实例化的过程&#xff0…

6 款顶级 Android 数据恢复软件列表

数据丢失可能会扰乱您的个人/企业生活,如果手动完成,可能很难恢复丢失的数据。Android 数据恢复软件是解决此问题的完美解决方案。这些工具可帮助您快速轻松地从 Android 设备恢复丢失的数据。它可以帮助您恢复照片、视频、笔记、联系人等。 我研究了市…

1. C++使用Thread类创建多线程的三种方式

1. 说明 使用Thread类创建线程对象的同时就会立刻启动线程,线程启动之后就要明确是等待线程结束(join)还是让其自主运行(detach),如果在线程销毁前还未明确上面的问题,程序就会报错。一般都会选…

webserve简介

目录 I/O分类I/O模型阻塞blocking非阻塞 non-blocking(NIO)IO复用信号驱动异步 webServerHTTP简介概述工作原理HTTP请求头格式HTTP请求方法HTTP状态码 服务器编程基本框架两种高效的事件处理模式Reactor模式Proactor模拟 Proactor 模式 线程池 I/O分类 …

字节岗位薪酬体系曝光,看完感叹:不服真不行

曾经的互联网是PC的时代,随着智能手机的普及,移动互联网开始飞速崛起。而字节跳动抓住了这波机遇,2015年,字节跳动全面加码短视频,从那以后,抖音成为了字节跳动用户、收入和估值的最大增长引擎。 自从字节…