PyQt5 仪表盘
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_()