当前位置:网站首页>pyqt5实现仪表盘
pyqt5实现仪表盘
2022-08-11 07:25:00 【芸兮】
大部分内容来自这里
讲解可以参考上边,区别是我提供完整可直接运行的代码
import math
import sys
from PyQt5.QtCore import Qt, QRectF
from PyQt5.QtGui import QColor, QFont, QPainter, QRadialGradient, QPolygon, QPen
from PyQt5.QtWidgets import QApplication, QWidget, QLCDNumber, QFrame
class Dashboard(QWidget):
def __init__(self, parent=None):
super(Dashboard, self).__init__(parent)
self.lcd = QLCDNumber(self)
self.setWindowTitle("QPainter测试")
self.setMinimumSize(600, 600)
# self.setMaximumSize(700, 700)
# 颜色设置
self.pieColorStart = QColor(63, 191, 127) # 绿色
self.pieColorMid = QColor(255, 155, 0) # 黄色色
self.pieColorEnd = QColor(222, 0, 0) # 红色
self.pointerColor = QColor(72, 203, 203) # 青色
self.startAngle = 60
self.endAngle = 60
self.minValue = 0
self.maxValue = 100
self.currentValue = 0
self.scaleMajor = 8
# 设置字符
self.font = QFont("宋体", 8)
self.font.setBold(True)
# LCD初始化
self.lcd_init()
# 其他设置
def setTitle(self, title):
self._title = title
def setValue(self, value):
self.currentValue = value
def paintEvent(self, event):
# 坐标轴变换 默认640*480
width = self.width()
height = self.height()
painter = QPainter(self) # 初始化painter
painter.translate(width / 2, height / 2) # 坐标轴变换,调用translate()将坐标原点平移至窗口中心
# 坐标刻度自适应
side = min(width, height)
painter.scale(side / 200.0, side / 200.0)
# 本项目中将坐标缩小为side/200倍,即画出length=10的直线,其实际长度应为10*(side/200)。
# 启用反锯齿,使画出的曲线更平滑
painter.setRenderHints(QPainter.Antialiasing | QPainter.TextAntialiasing)
painter.begin(self)
# 开始画图
self.drawColorPie(painter)
self.drawPointerIndicator(painter)
self.drawLine(painter)
self.drawText(painter)
# self.drawTitle(painter)
# 放置lcd并显示数值
# 根据自己屏幕的大小调整lcd的位置
self.lcd.setGeometry(self.width() / 2.15, self.height() / 9 * 7, self.width() / 10,
self.height() / 10) # 用setGeometry布局 2.25 , 9*7, 10,10
formValue = "%d" % self.currentValue # 数值的格式化显示
self.lcd.display(formValue) # 将指针所指的值显示在LCD屏幕上
def drawColorPie(self, painter): # 绘制三色环
painter.save() # save()保存当前坐标系
# print("drawColorPie")
# 设置扇形部分区域
radius = 99 # 半径
painter.setPen(Qt.NoPen)
rect = QRectF(-radius, -radius, radius * 2, radius * 2) # 扇形所在圆区域
# 计算三色圆环范围角度。green:blue:red = 1:2:1
angleAll = 360.0 - self.startAngle - self.endAngle # self.startAngle = 45, self.endAngle = 45
angleStart = angleAll * 0.25
angleMid = angleAll * 0.5
angleEnd = angleAll * 0.25
# 圆的中心部分填充为透明色,形成环的样式
rg = QRadialGradient(0, 0, radius, 0, 0) # 起始圆心坐标,半径,焦点坐标
ratio = 0.8 # 透明:实色 = 0.8 :1
# 绘制绿色环
rg.setColorAt(0, Qt.transparent) # 透明色
rg.setColorAt(ratio, Qt.transparent)
rg.setColorAt(ratio + 0.01, self.pieColorStart)
rg.setColorAt(1, self.pieColorStart)
painter.setBrush(rg)
painter.drawPie(rect, (270 - self.startAngle - angleStart) * 16, angleStart * 16)
# 绘制蓝色环
rg.setColorAt(0, Qt.transparent)
rg.setColorAt(ratio, Qt.transparent)
rg.setColorAt(ratio + 0.01, self.pieColorMid)
rg.setColorAt(1, self.pieColorMid)
painter.setBrush(rg)
painter.drawPie(rect, (270 - self.startAngle - angleStart - angleMid) * 16, angleMid * 16)
# 绘制红色环
rg.setColorAt(0, Qt.transparent)
rg.setColorAt(ratio, Qt.transparent)
rg.setColorAt(ratio + 0.01, self.pieColorEnd)
rg.setColorAt(1, self.pieColorEnd)
painter.setBrush(rg)
painter.drawPie(rect, (270 - self.startAngle - angleStart - angleMid - angleEnd) * 16, angleEnd * 16)
painter.restore() # restore()恢复坐标系
def drawPointerIndicator(self, painter):
painter.save()
# 绘制指针
# print("drawPointerIndicator")
radius = 58 # 指针长度
painter.setPen(Qt.NoPen)
painter.setBrush(self.pointerColor)
# (-5, 0), (0, -8), (5, 0)和(0, radius) 四个点绘出指针形状
# 绘制多边形做指针
pts = QPolygon()
pts.setPoints(-5, 0, 0, -8, 5, 0, 0, radius)
# print("radius:" + str(radius))
# 旋转指针,使得指针起始指向为0刻度处
painter.rotate(self.startAngle)
degRotate = (360.0 - self.startAngle - self.endAngle) / (self.maxValue - self.minValue) \
* (self.currentValue - self.minValue)
painter.rotate(degRotate)
painter.drawConvexPolygon(pts)
painter.restore()
def drawText(self, painter):
painter.save()
# 绘制刻度值
# print("drawText")
# 位置调整
startRad = 4
deltaRad = 0.6
radius = 63
offset = 5.5
for i in range(self.scaleMajor + 1): # self.scaleMajor = 8, 8个主刻度
# 正余弦计算
sina = math.sin(startRad - i * deltaRad)
cosa = math.cos(startRad - i * deltaRad)
# 刻度值计算
value = math.ceil((1.0 * i * (
(self.maxValue - self.minValue) / self.scaleMajor) + self.minValue))
# math.ceil(x):返回不小于x的最小整数
strValue = str(int(value))
# 字符的宽度和高度
textWidth = self.fontMetrics().width(strValue)
textHeight = self.fontMetrics().height()
# 字符串的起始位置。注意考虑到字符宽度和高度进行微调
x = radius * cosa - textWidth / 2
y = -radius * sina + textHeight / 4
painter.setFont(self.font)
painter.setPen(QColor(26, 95, 95)) # 还是用自己选的颜色
painter.drawText(x - offset, y, strValue + "%")
# Y为自己加的单位,可以不加,直接在 Title 中进行总体设置也行
painter.restore()
def drawLine(self, painter):
painter.save()
# 绘制刻度线
# print("drawLine")
radius = 79
painter.rotate(self.startAngle) # self.startAngle = 45,旋转45度
steps = self.scaleMajor # 8个刻度
angleStep = (360.0 - self.startAngle - self.endAngle) / steps # 刻度角
for i in range(steps + 1):
if i < 3:
color = self.pieColorStart
elif i < 7:
color = self.pieColorMid
else:
color = self.pieColorEnd
painter.setPen(QPen(color, Qt.SolidLine))
painter.drawLine(0, radius - 5, 0, radius)
painter.rotate(angleStep)
painter.restore()
def lcd_init(self):
self.lcd.setSmallDecimalPoint(False) # False:小数点单独占一位;True:小数点不占位
self.lcd.setDigitCount(2) # 最多显示2位数字
self.lcd.setFrameStyle(QFrame.NoFrame) # 无边框
self.lcd.setMode(QLCDNumber.Dec) # 十进制显示
self.lcd.setStyleSheet("color: rgb(0, 0, 0)") # 显示数字的颜色
self.lcd.setSegmentStyle(QLCDNumber.Flat) # 数字显示样式为flat,不向外凸
if __name__ == '__main__':
app = QApplication(sys.argv)
demo = Dashboard()
demo.show()
demo.setValue(88) # 设置指针指向
demo.setTitle("疲劳指数") # 设置图标题
sys.exit(app.exec_())
边栏推荐
猜你喜欢
从何跟踪伦敦金最新行情走势?
leetcode: 69. Square root of x
关于Excel实现分组求和最全文档
TF通过feature与label生成(特征,标签)集合,tf.data.Dataset.from_tensor_slices
The growth path of a 40W test engineer with an annual salary, which stage are you in?
【TA-霜狼_may-《百人计划》】图形3.7.2 command buffer简
Test cases are hard?Just have a hand
1046 punches (15 points)
Active users of mobile banking grew rapidly in June, hitting a half-year high
【Pytorch】nn.ReLU(inplace=True)
随机推荐
流式结构化数据计算语言的进化与新选择
Conditional statements in TF; where()
easyrecovery15数据恢复软件收费吗?功能强大吗?
1071 小赌怡情 (15 分)
4.1 - Support Vector Machines
【LaTex-错误和异常】\verb ended by end of line.原因是因为闭合边界符没有在\verb命令所属行中出现;\verb命令的正确和错误用法、verbatim环境的用法
CSDN21天学习挑战赛——封装(06)
易观分析联合中小银行联盟发布海南数字经济指数,敬请期待!
2021-08-11 For loop combined with multi-threaded asynchronous query and collect results
关于Excel实现分组求和最全文档
Tensorflow中使用tf.argmax返回张量沿指定维度最大值的索引
1002 写出这个数 (20 分)
关于Android Service服务的面试题
2022-08-10 mysql/stonedb-慢SQL-Q16-耗时追踪
TF中的条件语句;where()
tf中矩阵乘法
Project 1 - PM2.5 Forecast
1051 Multiplication of Complex Numbers (15 points)
1003 I want to pass (20 points)
break pad源码编译--参考大佬博客的总结