自定义组件——仪表盘

2023-05-16

在这里插入图片描述

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from math import *
import sys


class GaugePanel(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("GaugePanel")
        self.setMinimumWidth(300)
        self.setMinimumHeight(300)

        self.timer = QTimer()  # 窗口重绘定时器
        self.timer.timeout.connect(self.update)
        self.timer.start(100)

        self.testTimer = QTimer()
        self.testTimer.timeout.connect(self.testTimer_timeout_handle)

        self.lcdDisplay = QLCDNumber(self)
        self.lcdDisplay.setDigitCount(4)
        self.lcdDisplay.setMode(QLCDNumber.Dec)
        self.lcdDisplay.setSegmentStyle(QLCDNumber.Flat)
        self.lcdDisplay.setStyleSheet('border:2px solid green;color:green;background:silver')

        self._startAngle = 120  # 以QPainter坐标方向为准,建议画个草图看看
        self._endAngle = 60  # 以以QPainter坐标方向为准
        self._scaleMainNum = 10  # 主刻度数
        self._scaleSubNum = 10  # 主刻度被分割份数
        self._minValue = 0
        self._maxValue = 2000
        self._title = '×100rpm'
        self._value = 0
        self._minRadio = 100  # 缩小比例,用于计算刻度数字
        self._decimals = 0  # 小数位数

    @pyqtSlot()
    def testTimer_timeout_handle(self):
        self._value = self._value + 1
        if self._value > self._maxValue:
            self._value = self._minValue

    def setTestTimer(self, flag):
        if flag is True:
            self.testTimer.start(10)
        else:
            self.testTimer.stop()

    def setMinMaxValue(self, min, max):
        self._minValue = min
        self._maxValue = max

    def setTitle(self, title):
        self._title = title

    def setValue(self, value):
        self._value = value

    def setMinRadio(self, minRadio):
        self._minRadio = minRadio

    def setDecimals(self, decimals):
        self._decimals = decimals

    def paintEvent(self, event):
        side = min(self.width(), self.height())

        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)
        painter.translate(self.width() / 2, self.height() / 2)  # painter坐标系原点移至widget中央
        painter.scale(side / 200, side / 200)  # 缩放painterwidget坐标系,使绘制的时钟位于widge中央,即钟表支持缩放

        self.drawPanel(painter)  # 画外框表盘
        self.drawScaleNum(painter)  # 画刻度数字
        self.drawScaleLine(painter)  # 画刻度线
        self.drawTitle(painter)  # 画标题备注
        self.drawValue(painter)  # 画数显
        self.drawIndicator(painter)  # 画指针

    def drawPanel(self, p):
        p.save()
        radius = 100
        lg = QLinearGradient(-radius, -radius, radius, radius)
        lg.setColorAt(0, Qt.white)
        lg.setColorAt(1, Qt.black)
        p.setBrush(lg)
        p.setPen(Qt.NoPen)
        p.drawEllipse(-radius, -radius, radius * 2, radius * 2)

        p.setBrush(Qt.black)
        p.drawEllipse(-92, -92, 92 * 2, 92 * 2)
        p.restore()

    def drawScaleNum(self, p):
        p.save()
        p.setPen(Qt.white)
        startRad = self._startAngle * (3.14 / 180)
        stepRad = (360 - (self._startAngle - self._endAngle)) * (3.14 / 180) / self._scaleMainNum

        fm = QFontMetricsF(p.font())
        for i in range(0, self._scaleMainNum + 1):
            sina = sin(startRad + i * stepRad)
            cosa = cos(startRad + i * stepRad)

            tmpVal = i * ((self._maxValue - self._minValue) / self._scaleMainNum) + self._minValue
            tmpVal = tmpVal / self._minRadio
            s = '{:.0f}'.format(tmpVal)
            w = fm.size(Qt.TextSingleLine, s).width()
            h = fm.size(Qt.TextSingleLine, s).height()
            x = 80 * cosa - w / 2
            y = 80 * sina - h / 2
            p.drawText(QRectF(x, y, w, h), s)

        p.restore()

    def drawScaleLine(self, p):
        p.save()
        p.rotate(self._startAngle)
        scaleNums = self._scaleMainNum * self._scaleSubNum
        angleStep = (360 - (self._startAngle - self._endAngle)) / scaleNums
        p.setPen(Qt.white)

        pen = QPen(Qt.white)
        for i in range(0, scaleNums + 1):
            if i >= 0.8 * scaleNums:
                pen.setColor(Qt.red)

            if i % self._scaleMainNum is 0:
                pen.setWidth(2)
                p.setPen(pen)
                p.drawLine(64, 0, 72, 0)
            else:
                pen.setWidth(1)
                p.setPen(pen)
                p.drawLine(67, 0, 72, 0)
            p.rotate(angleStep)

        p.restore()

    def drawTitle(self, p):
        p.save()
        p.setPen(Qt.white)
        fm = QFontMetrics(p.font())
        w = fm.size(Qt.TextSingleLine, self._title).width()
        p.drawText(-w / 2, -45, self._title)
        p.restore()

    def drawValue(self, p):
        side = min(self.width(), self.height())
        w, h = side / 2 * 0.4, side / 2 * 0.2
        x, y = self.width() / 2 - w / 2, self.height() / 2 + side / 2 * 0.55
        self.lcdDisplay.setGeometry(x, y, w, h)

        ss = '{:.' + str(self._decimals) + 'f}'
        self.lcdDisplay.display(ss.format(self._value))

    def drawIndicator(self, p):
        p.save()
        polygon = QPolygon([QPoint(0, -2), QPoint(0, 2), QPoint(60, 0)])
        degRotate = self._startAngle + (360 - (self._startAngle - self._endAngle)) / (
                    self._maxValue - self._minValue) * (self._value - self._minValue)
        # 画指针
        p.rotate(degRotate)
        halogd = QRadialGradient(0, 0, 60, 0, 0)
        halogd.setColorAt(0, QColor(60, 60, 60))
        halogd.setColorAt(1, QColor(160, 160, 160))
        p.setPen(Qt.white)
        p.setBrush(halogd)
        p.drawConvexPolygon(polygon)
        p.restore()

        # 画中心点
        p.save()
        radGradient = QRadialGradient(0, 0, 10)
        radGradient = QConicalGradient(0, 0, -90)
        radGradient.setColorAt(0.0, Qt.darkGray)
        radGradient.setColorAt(0.5, Qt.white)
        radGradient.setColorAt(1.0, Qt.darkGray)
        p.setPen(Qt.NoPen)
        p.setBrush(radGradient)
        p.drawEllipse(-5, -5, 10, 10)
        p.restore()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    gp = GaugePanel()
    gp.show()
    gp.setTestTimer(True)
    app.exec_()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

自定义组件——仪表盘 的相关文章

  • ubuntu20.04分区方案 for deeplearning

    一共分出4个系统分区 1 设置efi引导 因为是u盘的uefi启动 xff0c 因此设置一个efi引导项 具体参数 xff1a 大小 500到1024mb即可 xff08 视自身的存储空间而定 xff09 新分区的类型 xff1a 逻辑分区
  • Linux重定向和管道符

    Linux重定向和管道符 1 Uid gid是什么 xff1f 2 linux中设置环境变量的几种方法3 管道命令符和通配符4 输入输出重定向 1 Uid gid是什么 xff1f 1 1 用户组 UID以及GID概念 用户组 xff1a
  • OpenFlow概念学习

    前言 OpenFlow交换机将原来完全由交换机 路由器控制的报文转发过程转化为由OpenFlow 交换机和控制服务器来共同完成 xff0c 目的交换机要通过of协议 xff08 OpenFlow Protocol xff09 经 安全通道
  • Ubuntu创建用户(组)与权限管理

    Ubuntu创建用户 xff08 组 xff09 与权限管理 创建用户与用户组创建和删除用户及用户组给用户配置sudo权限用户管理相关的命令 创建用户与用户组 在管理服务器时 xff0c 需要注意用户权限分配 xff0c 这样不会造成重大的
  • docker修改容器与宿主机端口映射

    1 查看容器id docker ps 2 进入容器安装目录 cd var lib docker containers 找到容器对应的文件夹 xff0c 容器id与文件夹前面的id是一样的 进入文件夹 cd 593f0dd680d77e901
  • Prometheus源码学习(1) 编译源码

    代码里面看不明白的变量或者函数可以通过两种方式观测它的值来了解其含义 一种是把代码片段摘出来 xff0c 写到一个测试程序里运行一下另一种时日志里打印它的值来观察 第一种比较简单易行 xff0c 但是代码片段要比较独立才好做 xff0c 第
  • ubuntu的命令&操作

    记录ubuntu系统使用中一些常用的操作 1 在ubuntu终端打开图像界面的文件夹 xff1a cd到指定的目录之后执行nautilus即可 参考 xff1a linux系统ubuntu中在命令行如何打开图形界面的文件夹 李照耀 博客园
  • Leetcode解题目录(Python版)

    Leetcode解题目录 xff08 Python版 xff09 题目目录1 排序算法2 哈希表3 动态规划 题目来源于LeetCode官网题库 xff0c 解题思路参考官网各大佬 xff0c 这里做一个目录方便大家查找 xff0c 另外方
  • error while loading shared libraries: libopencv_imgcorecs.so.3.4:: cannot open shared object file:

    ubuntu16 04的环境下 xff0c 编译成功C 43 43 代码 xff0c 同时也安装好了opencv3 4 在运行时却出现error xff1a error while loading shared libraries libo
  • 基于LQR的车辆LKA算法设计

    记录分享一下基于LQR控制算法的车辆LKA设计 通过carsim和simulink进行联合仿真 1控制算法设计 整体思路是通过车辆以及道路模型 得到控制器的输入 v 纵向速度 r 横摆角速度 y 侧向路径偏移 phi 横摆角误差 通过最优控
  • 软件框架

    1 概念 框架 xff08 framework xff09 是一个框子 指其约束性 xff0c 也是一个架子 指其支撑性 是一个基本概念上的结构 xff0c 用于去解决或者处理复杂的问题 框架这个广泛的定义使用的十分流行 xff0c 尤其在

随机推荐

  • 使用C++开发STM32 FreeRTOS工程与添加DSP库

    续上一篇文章的内容 由CubeMX构建的Makefile工程只支持C和汇编的编译 xff0c 而且FreeRTOS的代码也需要作为C代码编译 当我们想使用C 43 43 时 xff0c 需要做一些准备并且修改Makefile xff1b 另
  • CPU分时、中断和上下文切换

    准备知识 xff1a 实时和分时 嵌入式操作系统可以分为实时操作系统和分时操作系统两类 我们现实之中使用的绝大多数是分时操作系统 xff0c 比如windows或者linux 但是比如汽车就必须使用实时操作系统 xff0c 举一个经常使用的
  • 如何从AD导出PDF原理图

    https jingyan baidu com article 7c6fb428d4759080642c9017 html
  • PyQt ——setStyleSheet用法

    这个是CSS的手册 xff0c 所有的东西都可以参考这里 xff1a https css doyoe com 下面是CSS 的东西 字体属性 xff1a font 大小 font size x large 特大 xx small 极小 一般
  • QMessageBox

    span class token triple quoted string string 39 39 39 简介 PyQt5中 QMessage 例子 39 39 39 span span class token keyword impor
  • QInputDialog

    span class token triple quoted string string 39 39 39 简介 PyQt5中 QInputDialog 例子 39 39 39 span span class token keyword i
  • python cherry 用法

    CheeryPy是一个 Pythonic 的 面向对象的 Web 框架 xff0c 能够用于接受POST或者GET请求并进行回复 CheeryPy中文文档 xff1a Cherrypy 一个极简的python web框架 CherryPy
  • PyQt——简单进度条程序

    span class token keyword from span PyQt5 span class token punctuation span QtCore span class token keyword import span Q
  • PyQt——窗口居中

    span class token comment coding utf 8 span span class token keyword import span sys span class token keyword from span P
  • PyQt——分离UI主线程与工作线程

    span class token comment coding utf 8 span span class token keyword import span sys span class token keyword from span P
  • PyQt——信号与槽简介

    信号与槽简介 定义信号 操作信号
  • PyQt——信号与槽基础应用

    信号与槽有三种使用方法 xff0c 第一种是内置信号与槽的使用 xff0c 第二种是自定义信 号与槽的使用 xff0c 第三是装饰器的信号与槽的使用 由于第三种方法本质上是第一 种方法的衍生 内置信号与槽的使用 所谓内置信号与槽的使用 xf
  • PyQt——信号与槽函数快速进阶

    内置信号与槽函数 span class token keyword from span PyQt5 span class token punctuation span QtWidgets span class token keyword i
  • PyQt——自定义信号与槽的高级应用

    高级自定义信号与槽 span class token keyword from span PyQt5 span class token punctuation span QtCore span class token keyword imp
  • PyQt——键盘事件和鼠标事件

    PyQt为事件处理提供了两种机制 xff1a 高级的信号和槽机制 xff0c 以及低级的事件处理程序 PyQt为拦截和处理事件提供了5种不同的方式 xff0c 这里只介绍最常用的头两种方式 第一种是重新实现特定事件 xff0c 如键盘和鼠标
  • PyQt——按钮类控件QAbstractButton

    按钮类控件 QPushButton
  • PyQt——按钮类控件QPushButton

    span class token keyword import span sys span class token keyword from span PyQt5 span class token punctuation span QtCo
  • spss入门基本用法

    一 xff0e 数据 1 个案排序 xff1a 对数据视图中的某个个案进行排序 xff0c 具体排序规则可以点进去选择 2 变量排序 xff1a 对变量视图中某个变量进行排序 xff0c 具体规则可以点进去选择 3 转置 xff1a 行列互
  • 基于OMAPL138的linux平台8250快速串口实现--UART+EDMA

    本文源码基于dvsdk omapl138 evm 04 03 00 06 setuplinux程序包里的linux3 3 0版本的内核 实现EDMA支持UART功能主要修改dma和8250的源码 首先为OMAPL138的arm和DSP分配d
  • 自定义组件——仪表盘

    span class token keyword from span PyQt5 span class token punctuation span QtCore span class token keyword import span s