pyqt5用QPainter在扇形上面描绘数据点,并可点击提示

2024-08-21 18:28

本文主要是介绍pyqt5用QPainter在扇形上面描绘数据点,并可点击提示,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  1. 绘画底层图形
  2. 在图形内描绘数据点
  3. 点击数据点时悬浮提示内容

数据有距离和角度,来绘画数据点,实时检测数据插入,可以用多进程,通过共用队列来传递数据
在这里插入图片描述

需要自动更新绘图时,调用self.update(),此代码仅保留思路

class Alarm_widget(QWidget):message_signal = pyqtSignal(object)  # 自定义信号,发送给子窗口的消息def __init__(self):super().__init__()self.initUI()def initUI(self):self.init_width = 1100self.init_high = 800# self.setGeometry(100, 100, self.init_width, self.init_high)self.setWindowTitle('PyQt5 扇形和点绘制')# 创建一个定时器,用于在达到一定时间后关闭tooltipself.toolTip_time = QTimer(self)self.toolTip_time.timeout.connect(self.hide_tool_tip)self.time_hide_tip = 10000  # 设置Tip多长时间的显示,毫秒#插入测试数据self.data_points['data1'] = {'distance': 5000, 'angle': 12, 'color': QColor(255, 165, 0)}def paintEvent(self, event):qp = QPainter(self)qp.setRenderHint(QPainter.Antialiasing, True)  # 使用抗锯齿qp.begin(self)self.draw_pie_and_points(qp, self.data_points)qp.end()def draw_pie_and_points(self, qp, data_points:dict):"""画扇形和打点:param qp: QPainter:param data_points: 数据点位字典:return:"""pie_num = 4  # 扇形的数量widget_size = (int(self.width() / 2), int(self.height() / 2))  # 图形占窗口的比例self.center = QPointF(widget_size[0], widget_size[1] + 20)   # 圆心位置self.start_angle = 45 * 16 # 开始角度是从3点钟方向逆时针开始, 转换为16进制表示的角度self.span_angle = 90 * 16  # 结束角度if self.center.x() < self.center.y():  # 取尺寸最小的,防止超出屏幕radius_step = int(widget_size[0] / pie_num)  # 每多少像素代表10kmelse:radius_step = int(widget_size[1] / pie_num)self.point_radius = 5  # 告警点的半径大小for i in range(0, 4):radius = (4-i) * radius_step# 绘制扇形qp.setBrush(QBrush(QColor(213, 226, 247)))# qp.setPen(QPen(Qt.black, 1, Qt.DashLine)) # 线宽1,线型为虚线qp.drawPie(self.center.x() - radius, self.center.y() - radius, 2 * radius, 2 * radius, self.start_angle, self.span_angle)# 中线radius = 4 * radius_stepqp.setPen(QPen(Qt.black, 1, Qt.DashLine)) # 黑色,像素宽,虚线样式qp.drawLine(self.center.x(), self.center.y(), self.center.x(), (self.center.y() - radius))num = 0  # 计数多少数据# 绘制短线和旁边的名称line_height = 40  # 每行数据之间的垂直间隔text_offset = 20  # 文本与线条之间的水平间隔font = QFont()font.setPointSize(12)  # 设置字体大小为12点# 角度转弧度,计算数据详情列表的左侧位置angle_rad = math.radians(180-(self.start_angle+self.span_angle)/16)# 计算余弦值cos_value = math.cos(angle_rad) * 4 * radius_stepresult_list_posx = self.center.x() - cos_valuefor data, meta in data_points.items():distance = meta['distance']color_value = meta['color']# 设置点的颜色和大小qp.setPen(QPen(color_value, 8))# 距离 转换 像素距离pix_distance = distance * radius_step / 10000if 'angle' in meta:  # 存在角度值,则画点angle = meta['angle']# 将极坐标转换为直角坐标x = self.center.x() + pix_distance * math.cos(math.radians(90 - angle))y = self.center.y() - pix_distance * math.sin(math.radians(90 - angle))self.points[data] = (x, y)# 绘制点(使用 drawEllipse 方法绘制很小的圆来近似点)qp.drawEllipse(QPointF(x, y), self.point_radius - 1, self.point_radius - 1)# 在下面列表展示详情qp.setFont(font)qp.setBrush(color_value)  # 设置填充颜色qp.drawEllipse(result_list_posx + 3, self.center.y() + 20 + line_height * num, 14, 14)  # 绘制圆点qp.setPen(Qt.black)  # 设置文本颜色为黑色text = "提示内容1"qp.drawText(result_list_posx + 20 + text_offset, self.center.y() + 33 + line_height * num, text)num += 1def mousePressEvent(self, event):# 检测鼠标是否在点的附近pos = event.pos()check_radius = self.point_radius + 2  # 检测鼠标点击半径,比告警点宽一点点# self.lastClickedPoint = Nonefor data, position in self.points.items():x = position[0]y = position[1]# 检查鼠标是否在点的矩形区域内(使用半径扩展)rect = QRect(x - check_radius, y - check_radius, 2 * check_radius, 2 * check_radius)if rect.contains(pos):# self.lastClickedPoint = QPoint(x, y)tip = data[-4:] + ': ' + self.data_points[data]['collect_time'][5:-3]# 显示提示,并设置定时器self.show_tool_tip(pos, tip)self.toolTip_time.start(self.time_hide_tip)  # 到时隐藏提示breakelse:for imsi, r in self.arcs_radius.items():if self.is_point_on_arc(r, self.start_angle, self.span_angle, pos, self.point_radius):# print("点击点在圆弧上")tip = imsi[-4:] + ': ' + self.data_points[imsi]['collect_time'][5:-3]# 显示提示,并设置定时器self.show_tool_tip(pos, tip)self.toolTip_time.start(self.time_hide_tip)  # 到时隐藏提示breakelse:# 如果没有在任何点附近,隐藏工具提示self.hide_tool_tip()def resizeEvent(self, event):# 当窗口大小改变时,触发重绘self.update()def show_tool_tip(self, pos, text:str):"""在指定坐标显示提示:param pos: 信息提示的坐标:param text: 提示内容:return:"""self.toolTipLabel.setText(f"{text}")# 将label移动到鼠标位置附近,但可能需要根据需要进行调整以避免遮挡label_pos = pos + QPoint(20, -self.toolTipLabel.height() - 20)# 显示CustomToolTip在widget的指定位置附近screen = QApplication.desktop().screenGeometry()# widget_rect = self.geometry()# widget_top_left = self.mapToGlobal(widget_rect.topLeft())# # 计算位置,确保ToolTip不会超出屏幕# x = widget_top_left.x() + pos.x()# y = widget_top_left.y() + pos.y()x = label_pos.x()y = label_pos.y()if x + self.toolTipLabel.width() > screen.width():x = screen.width() - self.toolTipLabel.width()if y + self.toolTipLabel.height() > screen.height():y = screen.height() - self.toolTipLabel.height()self.toolTipLabel.move(x, y)self.toolTipLabel.show()def hide_tool_tip(self):self.toolTipLabel.hide()self.toolTip_time.stop()

这篇关于pyqt5用QPainter在扇形上面描绘数据点,并可点击提示的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1093932

相关文章

Java中注解与元数据示例详解

《Java中注解与元数据示例详解》Java注解和元数据是编程中重要的概念,用于描述程序元素的属性和用途,:本文主要介绍Java中注解与元数据的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参... 目录一、引言二、元数据的概念2.1 定义2.2 作用三、Java 注解的基础3.1 注解的定义3.2 内

将sqlserver数据迁移到mysql的详细步骤记录

《将sqlserver数据迁移到mysql的详细步骤记录》:本文主要介绍将SQLServer数据迁移到MySQL的步骤,包括导出数据、转换数据格式和导入数据,通过示例和工具说明,帮助大家顺利完成... 目录前言一、导出SQL Server 数据二、转换数据格式为mysql兼容格式三、导入数据到MySQL数据

C++中使用vector存储并遍历数据的基本步骤

《C++中使用vector存储并遍历数据的基本步骤》C++标准模板库(STL)提供了多种容器类型,包括顺序容器、关联容器、无序关联容器和容器适配器,每种容器都有其特定的用途和特性,:本文主要介绍C... 目录(1)容器及简要描述‌php顺序容器‌‌关联容器‌‌无序关联容器‌(基于哈希表):‌容器适配器‌:(

C#提取PDF表单数据的实现流程

《C#提取PDF表单数据的实现流程》PDF表单是一种常见的数据收集工具,广泛应用于调查问卷、业务合同等场景,凭借出色的跨平台兼容性和标准化特点,PDF表单在各行各业中得到了广泛应用,本文将探讨如何使用... 目录引言使用工具C# 提取多个PDF表单域的数据C# 提取特定PDF表单域的数据引言PDF表单是一

一文详解Python中数据清洗与处理的常用方法

《一文详解Python中数据清洗与处理的常用方法》在数据处理与分析过程中,缺失值、重复值、异常值等问题是常见的挑战,本文总结了多种数据清洗与处理方法,文中的示例代码简洁易懂,有需要的小伙伴可以参考下... 目录缺失值处理重复值处理异常值处理数据类型转换文本清洗数据分组统计数据分箱数据标准化在数据处理与分析过

大数据小内存排序问题如何巧妙解决

《大数据小内存排序问题如何巧妙解决》文章介绍了大数据小内存排序的三种方法:数据库排序、分治法和位图法,数据库排序简单但速度慢,对设备要求高;分治法高效但实现复杂;位图法可读性差,但存储空间受限... 目录三种方法:方法概要数据库排序(http://www.chinasem.cn对数据库设备要求较高)分治法(常

Python将大量遥感数据的值缩放指定倍数的方法(推荐)

《Python将大量遥感数据的值缩放指定倍数的方法(推荐)》本文介绍基于Python中的gdal模块,批量读取大量多波段遥感影像文件,分别对各波段数据加以数值处理,并将所得处理后数据保存为新的遥感影像... 本文介绍基于python中的gdal模块,批量读取大量多波段遥感影像文件,分别对各波段数据加以数值处

使用MongoDB进行数据存储的操作流程

《使用MongoDB进行数据存储的操作流程》在现代应用开发中,数据存储是一个至关重要的部分,随着数据量的增大和复杂性的增加,传统的关系型数据库有时难以应对高并发和大数据量的处理需求,MongoDB作为... 目录什么是MongoDB?MongoDB的优势使用MongoDB进行数据存储1. 安装MongoDB

Python MySQL如何通过Binlog获取变更记录恢复数据

《PythonMySQL如何通过Binlog获取变更记录恢复数据》本文介绍了如何使用Python和pymysqlreplication库通过MySQL的二进制日志(Binlog)获取数据库的变更记录... 目录python mysql通过Binlog获取变更记录恢复数据1.安装pymysqlreplicat

Linux使用dd命令来复制和转换数据的操作方法

《Linux使用dd命令来复制和转换数据的操作方法》Linux中的dd命令是一个功能强大的数据复制和转换实用程序,它以较低级别运行,通常用于创建可启动的USB驱动器、克隆磁盘和生成随机数据等任务,本文... 目录简介功能和能力语法常用选项示例用法基础用法创建可启动www.chinasem.cn的 USB 驱动