PyQt6+pyqtgraph折线图绘制显示

1、实现效果

2、环境:

确认已经安装pyqtgraph的模块,如果没有安装,使用命令安装:

pip install pyqtgraph

3、代码实现:

绘制折线函数:

import sys
import random
from PySide6.QtWidgets import QApplication, QGraphicsView, QGraphicsScene, QGraphicsItem
from PySide6.QtCore import Qt, QPointF, QRectF, QTimer
from PySide6.QtGui import QPainter, QPen, QColor, QFont

class ScrollableLineGraph(QGraphicsItem):
    def __init__(self, data):
        """
        初始化线图项,设置初始显示范围和数据
        :param data: 要显示的数据列表
        """
        super().__init__()
        self.data = data
        self.current_start = 0  # 当前显示的起始索引
        self.bounding_rect = QRectF(0, 0, 900, 200)  # 线图的边界矩形

    def boundingRect(self):
        """
        返回线图的边界矩形,用于确定绘制区域
        :return: 矩形边界
        """
        return self.bounding_rect

    def paint(self, painter, option, widget):
        """
        绘制线图,包括坐标轴、刻度和数据线
        :param painter: 绘制工具
        :param option: 绘制选项
        :param widget: 关联的窗口部件
        """
        painter.setRenderHint(QPainter.Antialiasing)  # 开启抗锯齿
        axis_pen = QPen(QColor(255, 255, 255))  # 坐标轴线颜色
        line_pen = QPen(QColor(255, 0, 0))  # 数据线颜色
        text_font = QFont()  # 字体设置

        # 绘制x轴
        painter.setPen(axis_pen)
        painter.drawLine(0, 200, 900, 200)
        # 绘制x轴刻度和标签
        for i in range(0, 20, 1):
            x = (i - self.current_start) * 45
            if 0 <= x < 900:
                painter.drawLine(x, 200, x, 210)
                painter.drawText(x - 5, 220, str(i + self.current_start))

        # 绘制y轴
        painter.drawLine(0, 0, 0, 200)
        # 绘制y轴刻度和标签
        for i in range(0, 5):
            y = 200 - 45 * i
            painter.drawLine(-5, y, 0, y)
            painter.drawText(-20, y - 5, str(i * 20))  #10:表示Y坐标值间隔大小
        # 绘制y轴刻度和标签,给每个标签添加上横向网格,网格为点状虚线
        for i in range(0, 5):
            y = 200 - 45 * i
            # 网格为点状虚线
            painter.setPen(QPen(QColor(128, 128, 128), 0.5, Qt.DashLine))
            # painter.drawLine(-5, y, 0, y)
            # painter.drawText(-20, y - 5, str(i * 10))
            painter.drawLine(0, y, 900, y)
        # 假设已经初始化了painter对象等必要的准备工作

        # 定义一些常量,提高代码的可读性
        CANVAS_HEIGHT = 200
        SCALE_FACTOR = 45
        LABEL_OFFSET = -20
        GRID_LINE_WIDTH = 0.5
        GRID_LINE_COLOR = QColor(128, 128, 128)
        GRID_LINE_STYLE = Qt.DashLine
        MAX_LABELS = 10

        # 新增:封装绘制网格线和刻度标签的函数
        def draw_scale_and_grid(painter, y_position, label):
            """
            绘制y轴刻度和标签以及对应的横向网格线
            :param painter: QPainter对象,用于绘制
            :param y_position: y轴位置
            :param label: 刻度标签的文本
            """
            try:
                # 绘制网格线
                painter.setPen(QPen(GRID_LINE_COLOR, GRID_LINE_WIDTH, GRID_LINE_STYLE))
                painter.drawLine(-5, y_position, 0, y_position)

                # 绘制刻度标签
                painter.drawText(-LABEL_OFFSET, y_position - 5, label)

                # 绘制右侧网格线
                painter.drawLine(0, y_position, 900, y_position)
            except Exception as e:
                print(f"Error during drawing scale and grid: {e}")


        # 主绘制逻辑
        try:
            for i in range(MAX_LABELS + 1):  # 由于范围是从0到10,因此循环次数应为MAX_LABELS + 1
                y = CANVAS_HEIGHT - SCALE_FACTOR * i
                # 检查y位置是否在画布内,若不在则跳过
                if y < 0:
                    break
                label = str(i * 10)
                # draw_scale_and_grid(painter, y, label)
        except Exception as e:
            print(f"Unexpected error occurred: {e}")

        # 假设在这段代码的末尾,有适当的资源释放逻辑,例如painter对象的销毁等

        # 设置字体
        painter.setFont(text_font)
        # 绘制x轴和y轴标签
        painter.drawText(900, 205, "Time")
        painter.rotate(-90)
        painter.drawText(-30,10, "Value")
        painter.rotate(90)

        # 绘制数据线
        painter.setPen(line_pen)
        painter.setRenderHint(QPainter.SmoothPixmapTransform)
        last_point = QPointF(0, 200 - self.data[self.current_start])
        for i in range(self.current_start, min(self.current_start + 50, len(self.data))):
            x = (i - self.current_start) * 45
            y = 200 - self.data[i]
            painter.drawLine(last_point, QPointF(x, y))
            last_point = QPointF(x, y)

在QT Designer的Widget页面添加Graphics View,命名为graphicsView

在页面类中定义图表初始化和数据更新方法:

  def GraphWidget_uiInit(self):
    data = []
    scene = QGraphicsScene(self.graphicsView)
    self.graphicsView.setScene(scene)
    self.data_graph = ScrollableLineGraph(data)
    scene.addItem(self.data_graph)
    scene.setBackgroundBrush
    self.graphicsView.setRenderHint(QPainter.Antialiasing)
    self.graphicsView.setFixedSize(960, 240)
    self.graphicsView.setSceneRect(0, 0, 900, 220)
    self.graphicsView.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)

    # # 设置定时器,用于动态更新数据
    # self.timer = QTimer(self)
    # self.timer.timeout.connect(self.update_data)
    # self.timer.start(60)  # 每500毫秒触发一次

  def update_data(self):
    #随机数据
    # new_data = random.randint(0, 100)
    # self.data_graph.data.append(new_data)

    #将字符串数据转换成int类型的列表数据
    dataStr8 = "100 30 178 100 69 60 98 98 79 50 30 20 29 58 69 39 98 29 32"
    list_from_string8 = dataStr8.split()
    number_list8 = list(map(int, list_from_string8))

    self.data_graph.data = number_list8
    self.data_graph.current_start = max(0, len(self.data_graph.data) - 50)
    self.data_graph.update()

参考博文:https://blog.csdn.net/hyd_csdn/article/details/140644014

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux---ps命令

​​​​​​Linux ps 命令 | 菜鸟教程 (runoob.com) process status 用于显示进程的状态 USER: 用户名&#xff0c;运行此进程的用户名。PID: 进程ID&#xff08;Process ID&#xff09;&#xff0c;每个进程的唯一标识号%CPU: 进程当前使用的CPU百分比%MEM: 进程当前使用的…

高新技术行业中的知识管理:关键性、挑战、策略及工具应用

知识管理的关键性 在瞬息万变的信息时代&#xff0c;知识已成为高新技术行业的核心竞争要素。知识管理&#xff0c;这一旨在高效组织、整合并应用企业内外部知识资源的管理策略&#xff0c;对于推动高新技术企业的持续创新与发展至关重要。它不仅能够激发研发团队的创造力&…

IDEA 2024安装指南(含安装包以及使用说明 cannot collect jvm options 问题 四)

汉化 setting 中选择插件 完成 安装出现问题 1.可能是因为之前下载过的idea&#xff0c;找到连接中 文件&#xff0c;卸载即可。

【MyBatis】全局配置文件—mybatis.xml 创建xml模板

文章目录 模板文件配置元素typeAliasessettings 模板文件 创建模板 按照顺序打开【File】–>【settings】–>【Editor】–>【File and Code Templates】&#xff08;或直接搜索&#xff09; <?xml version"1.0" encoding"UTF-8" ?> <…

uni-app 发布媒介功能(自由选择媒介类型的内容) 设计

1.首先明确需求 我想做一个可以选择媒介的内容&#xff0c;来进行发布媒介的功能 &#xff08;媒介包含&#xff1a;图片、文本、视频&#xff09; 2.原型设计 发布-编辑界面 通过点击下方的加号&#xff0c;可以自由选择添加的媒介类型 但是因为预览中无法看到视频的效果&…

【Go】-go中的锁机制

目录 一、锁的基础知识 1. 互斥量/互斥锁 2. CAS&#xff08;compare and swap&#xff09; 3. 自旋锁 4. 读写锁 5. 乐观锁 & 悲观锁 6. 死锁 二、go中锁机制 1. Mutex-互斥锁 2. RWMutex-读写锁 2.1 RWMutex流程概览 2.2 写锁饥饿问题 2.3. golang的读写锁源…

Python 使用 Selenuim进行自动化点击入门,谷歌驱动,以百度为例

一、首先要下载谷歌驱动 1.&#xff08;打开谷歌浏览器 - 设置 - 关于谷歌&#xff0c;查看谷歌浏览器版本&#xff0c;否则不对应无法调用&#xff0c;会提示&#xff1a;selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This versio…

RCVS:A Unifed Registration and FusionFramework for Video Streams 译文

摘要:红外与可见光的跨模态配准与融合可以生成更全面的目标和场景信息表示。以前的框架主要关注于解决模态差异以及保留不同模态信息对不同静态图像对之间配准和融合任务性能的影响。然而&#xff0c;这些框架忽略了在现实世界设备上的实际部署&#xff0c;特别是在视频流的背景…

JDBC编程---Java

目录 一、数据库编程的前置 二、Java的数据库编程----JDBC 1.概念 2.JDBC编程的优点 三.导入MySQL驱动包 四、JDBC编程的实战 1.创造数据源&#xff0c;并设置数据库所在的位置&#xff0c;三条固定写法 2.建立和数据库服务器之间的连接&#xff0c;连接好了后&#xff…

Python 抓取笑话内容并存入 CSV

在互联网上&#xff0c;有许多有趣的内容等待我们去挖掘和收集。今天&#xff0c;我们就来深入了解一段 Python 代码&#xff0c;它能够帮助我们从指定网站抓取笑话内容&#xff0c;并将其整理保存为 CSV 文件&#xff0c;方便后续查看和分析。 结果展示&#xff08;文末附完整…

Redis-09 SpringBoot集成Redis

Jedis 和 lettuce 基本已经过时 集成RedisTemplate 单机 1.建 Modul 2.改pom <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instanc…

Linux:自定义Shell

本文旨在通过自己完成一个简单的Shell来帮助理解命令行Shell这个程序。 目录 一、输出“提示” 二、获取输入 三、切割字符串 四、执行指令 1.子进程替换 2.内建指令 一、输出“提示” 这个项目基于虚拟机Ubuntu22.04.5实现。 打开终端界面如图所示。 其中。 之前&#x…

夜天之书 #104 开源软件有断供的风险吗?

近期&#xff0c;Linux 上游因为受美国出口管制条例的影响&#xff0c;将移除部分开发者的 MAINTAINER 权限&#xff0c;引起了新一轮对开源依赖的重新评估。 关于其中开源精神和社群治理的讨论&#xff0c;卫 Sir 的两篇文章已经讨论得比较清楚&#xff08;见尾注&#xff09;…

tensorforce(dqn框架)安装

win7 64位操作系统 python版本&#xff1a;3.8.10 pip install tensorflow 默认的tensorflow的版本是2.31.0&#xff0c;安装tensorforce后自动升级到3.6.0 tensorflow:升级到3.6.0 keras&#xff1a;升级到3.6.0 tensorforce安装 pip3 install tensorforce protobuf 需要降到…

STM32抢占优先级不生效

板类型&#xff1a;STM32F103精英开发板代码背景&#xff1a; 设置了USART1中断和KEY_UP中断(使用EXTI0外部中断)两个中断的优先级分组都设为2&#xff08;2bit抢占优先级&#xff0c;2bit响应优先级)EXTI0中断抢占优先级设为3&#xff0c; 响应优先级设为3USART1抢占优先级设…

4.1_未授权漏洞

未授权漏洞 成因&#xff1a;配置错误&#xff0c;默认口令&#xff08;弱口令&#xff09;&#xff0c;接口配置不当&#xff1b;未授权漏洞 漏洞利用方式 Redis 未授权访问漏洞 Getshell方式 写入webshell&#xff1b; 连接目标redis&#xff1a;redis-cli -h 192.168.7…

快速识别模型:simple_ocr,部署教程

快速识别图片中的英文、标点符号、数学符号、Emoji, 模型会输出图片中文字行的坐标位置、最低得分、识别结果。当前服务用到的模型&#xff1a;检测模型、数字识别、英文符号识别。 一、部署流程 1.更新基础环境 apt update2.安装miniconda wget https://repo.anaconda.com/…

衡山派D133EBS 开发环境安装及SDK编译烧写镜像烧录

1.创建新文件夹&#xff0c;用来存放SDK包&#xff08;其实本质就是路径要对就ok了&#xff09;&#xff0c;右键鼠标通过Open Git Bash here来打开git 输入命令 git clone --depth1 https://gitee.com/lcsc/luban-lite.git 来拉取&#xff0c;如下所示&#xff1a;&#xff0…

蓝桥杯不知道叫什么题目

小蓝有一个整数&#xff0c;初始值为1&#xff0c;他可以花费一些代价对这个整数进行变换。 小蓝可以花贵1的代价将教数增加1。 小蓝可以花费3的代价将整数增加一个值,这个值是整数的数位中最大的那个(1到9) .小蓝可以花费10的代价将整数变为原来的2倍, 例如&#xff0c;如果整…

读取mysql、kafka数据筛选后放入mysql

要求&#xff1a; 从kafka的topic-car中读取卡口数据&#xff0c;将超速车辆写入mysql的t_monitor_info表 当通过卡口的车速超过该卡口限速的1.2倍 就认定为超速。 G107 1&#xff09;卡口数据格式如下&#xff1a; action_time long --摄像头拍摄时间戳&#xff0c;精确到秒…