LISHUZUOXUN_yangjiang/LSZXPagesLibrary/hr_plot_graph_opengl.py

146 lines
7.7 KiB
Python
Raw Normal View History

2024-09-23 14:54:15 +08:00
import sys # 导入系统模块
from PyQt5.QtCore import Qt # 从 PyQt5.QtCore 模块导入 Qt
from PyQt5.QtWidgets import QApplication, QFrame, QLabel, QHBoxLayout, QVBoxLayout, QOpenGLWidget # 从 PyQt5.QtWidgets 模块导入所需组件
from OpenGL.GL import * # 导入 OpenGL.GL 模块中的所有内容
from OpenGL.GLU import * # 导入 OpenGL.GLU 模块中的所有内容
import pyqtgraph as pg # 导入 pyqtgraph 并命名为 pg
class HrPlotGraph(QOpenGLWidget): # 定义 HrPlotGraph 类,继承自 QOpenGLWidget
def __init__(self): # 初始化方法
super().__init__() # 调用父类的初始化方法
self.setWindowTitle("心率监测") # 设置窗口标题
# 初始化各个组件
self.icon_widget = self._init_icon_widget() # 初始化图标组件
self.title_widget = self._init_title_widget() # 初始化标题组件
self.value_label = self._init_value_label() # 初始化当前心率显示组件
self.max_label = self._init_max_label() # 初始化最大心率显示组件
self.plot_widget_hr, self.plot_item_hr = self._init_plot_widget() # 初始化绘图组件
# 设置标题布局
self.title_layout = QHBoxLayout() # 创建水平布局
self.title_layout.addWidget(self.icon_widget, 1) # 将图标组件添加到布局中,占据 10% 的屏幕宽度
self.title_layout.addWidget(self.title_widget, 9) # 将标题组件添加到布局中,占据 90% 的屏幕宽度
# 设置心率值布局
self.values_title_layout = QVBoxLayout() # 创建垂直布局
self.values_title_layout.addWidget(self.value_label, 1) # 将当前心率显示组件添加到布局中,占据 50% 的垂直空间
self.values_title_layout.addWidget(self.max_label, 1) # 将最大心率显示组件添加到布局中,占据 50% 的垂直空间
# 设置显示布局
self.display_layout = QHBoxLayout() # 创建水平布局
self.display_layout.addLayout(self.values_title_layout, 1) # 将心率值布局添加到布局中,占据 40% 的水平空间
self.display_layout.addWidget(self.plot_widget_hr, 3) # 将绘图组件添加到布局中,占据 60% 的水平空间
# 主布局
self.main_layout = QVBoxLayout() # 创建垂直布局
self.main_layout.addLayout(self.title_layout, 1) # 将标题布局添加到主布局中,占据 20% 的垂直空间
self.main_layout.addLayout(self.display_layout, 4) # 将显示布局添加到主布局中,占据 80% 的垂直空间
self.setLayout(self.main_layout) # 将主布局设置为窗口的布局
self.setStyleSheet( # 设置样式表
"background-color: #ffffff;" # 背景颜色为白色
"border: 1px solid #bbbbbb;" # 边框颜色为灰色
"border-radius: 4px;" # 边框圆角
"margin-right: 20px;" # 右边距
"margin-top: 0px" # 上边距
)
def initializeGL(self): # 初始化 OpenGL
glClearColor(1.0, 1.0, 1.0, 1.0) # 设置清除颜色为白色
def resizeGL(self, w, h): # 调整 OpenGL 视口大小
glViewport(0, 0, w, h) # 设置 OpenGL 视口大小
glMatrixMode(GL_PROJECTION) # 设置当前矩阵为投影矩阵
glLoadIdentity() # 重置当前矩阵为单位矩阵
gluOrtho2D(0, w, h, 0) # 设置正交投影,匹配窗口宽度和高度
glMatrixMode(GL_MODELVIEW) # 设置当前矩阵为模型视图矩阵
glLoadIdentity() # 重置当前矩阵为单位矩阵
def paintGL(self): # 绘制 OpenGL 内容
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # 清除颜色缓冲区和深度缓冲区
def set_data(self, data, max_data): # 设置心率数据和最大心率值
self.plot_item_hr.setData(data) # 更新绘图数据
self.max_label.setText(f"最大心率:{max_data}次/分钟") # 更新最大心率显示
if data: # 如果有数据
self.value_label.setText(f'当前心率:{data[-1]}次/分钟') # 更新当前心率显示
@staticmethod
def _init_icon_widget(): # 初始化图标组件
img = QLabel() # 创建 QLabel 对象
img.setStyleSheet( # 设置样式表
"border-image: url(assets/heart.png);" # 设置图标图片
"background-size: contain;" # 背景大小自适应
"background-repeat: no-repeat;" # 背景不重复
"background-position: center;" # 背景居中
)
img.setAlignment(Qt.AlignCenter) # 图标居中对齐
img.setScaledContents(True) # 图标大小自动缩放
return img # 返回图标组件
@staticmethod
def _init_title_widget(): # 初始化标题组件
title = QLabel("心率") # 创建 QLabel 对象并设置文本
title.setStyleSheet( # 设置样式表
"font: 30px \"Microsoft YaHei UI\";" # 设置字体和大小
"color: #2c2c2c;" # 设置字体颜色
"border: none;" # 无边框
)
title.setContentsMargins(20, 4, 20, 4) # 设置边距
return title # 返回标题组件
@staticmethod
def _init_value_label(): # 初始化当前心率显示组件
value_label = QLabel('当前心率:次/分钟') # 创建 QLabel 对象并设置文本
value_label.setFrameShape(QFrame.Box) # 设置框架形状
value_label.setLineWidth(0) # 设置线宽
value_label.setStyleSheet( # 设置样式表
"border: none;" # 无边框
"background-color: #ececec;" # 背景颜色
"margin-right: 10px;" # 右边距
"margin: 0px 0px 0px 0px;" # 四周边距
"border-radius: 5px;" # 边框圆角
"font: 24px \"Microsoft YaHei UI\";" # 设置字体和大小
)
value_label.setAlignment(Qt.AlignCenter) # 文本居中对齐
return value_label # 返回当前心率显示组件
@staticmethod
def _init_max_label(): # 初始化最大心率显示组件
max_label = QLabel('最大心率:次/分钟') # 创建 QLabel 对象并设置文本
max_label.setFrameShape(QFrame.Box) # 设置框架形状
max_label.setLineWidth(0) # 设置线宽
max_label.setStyleSheet( # 设置样式表
"border: none;" # 无边框
"background-color: #ececec;" # 背景颜色
"margin-right: 10px;" # 右边距
"margin: 0px 0px 0px 0px;" # 四周边距
"border-radius: 5px;" # 边框圆角
"font: 24px \"Microsoft YaHei UI\";" # 设置字体和大小
)
max_label.setAlignment(Qt.AlignCenter) # 文本居中对齐
return max_label # 返回最大心率显示组件
@staticmethod
def _init_plot_widget(): # 初始化绘图组件
plot_widget_hr = pg.PlotWidget() # 创建 PlotWidget 对象
plot_item_hr = plot_widget_hr.plot() # 创建 PlotDataItem 对象
plot_widget_hr.getAxis('bottom').setTicks([]) # 不显示 x 轴坐标点
plot_widget_hr.setBackground('w') # 设置白色网格背景
plot_widget_hr.showGrid(x=True, y=True) # 显示网格
plot_widget_hr.setYRange(0, 100) # 设置 y 轴范围
pen = pg.mkPen(color='#5c7bd9', width=3) # 修改线条颜色和粗细
plot_item_hr.setPen(pen) # 设置绘图线条样式
return plot_widget_hr, plot_item_hr # 返回绘图组件和绘图项
if __name__ == '__main__': # 主程序入口
app = QApplication(sys.argv) # 创建应用程序对象
widget = HrPlotGraph() # 创建 HrPlotGraph 对象
widget.resize(800, 600) # 调整窗口大小
widget.show() # 显示窗口
sys.exit(app.exec_()) # 进入应用程序主循环