Skip to content

Instantly share code, notes, and snippets.

@eyllanesc
Created June 26, 2018 20:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eyllanesc/8565de8bcf25fb2d84bd488935d173c0 to your computer and use it in GitHub Desktop.
Save eyllanesc/8565de8bcf25fb2d84bd488935d173c0 to your computer and use it in GitHub Desktop.
# -*- coding: utf-8 -*-
from BackgroundWidget import BackgroundWidget
class AbstractMeter(BackgroundWidget):
def __init__(self, parent=None):
BackgroundWidget.__init__(self, parent=parent)
self.mValue = 0.0
self.mMinimal = 0.0
self.mNominal = 25
self.mCritical = 75
self.mMaximal = 100
def critical(self):
return self.mCritical
def setCritical(self, val):
if self.mCritical != val:
self.mCritical = val
self.mModified = True
self.update()
def nominal(self):
return self.mNominal
def setNominal(self, val):
if self.mNominal != val:
self.mNominal = val
self.mModified = True
self.update()
def minimal(self):
return self.mMinimal
def setMinimal(self, val):
if self.mMinimal != val:
self.mMinimal = val
self.mModified = True
self.update()
def maximal(self):
return self.mMaximal
def setMaximal(self, val):
if self.mMaximal != val:
self.mMaximal = val
self.mModified = True
self.update()
def value(self):
return self.mValue
def setValue(self, val):
if self.mValue != val:
self.mValue = val
self.update()
# -*- coding: utf-8 -*-
from PyQt5.QtGui import QPixmap, QColor, QPainter
from PyQt5.QtWidgets import QWidget
class BackgroundWidget(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent=parent)
self.mModified = True
self.mPixmap = QPixmap()
self.value_background = True
def draw_background(self, painter):
pass
def draw_value(self, painter):
pass
def draw_back(self):
if self.mModified or self.mPixmap.size() != self.size():
del self.mPixmap
self.mPixmap = QPixmap(self.size())
self.mPixmap.fill(QColor(0, 0, 0, 0))
painter = QPainter(self.mPixmap)
self.draw_background(painter)
self.mModified = False
painter = QPainter(self)
painter.drawPixmap(0, 0, self.mPixmap)
def draw_val(self):
painter = QPainter(self)
self.draw_value(painter)
def paintEvent(self, event):
if self.value_background:
self.draw_val()
self.draw_back()
else:
self.draw_back()
self.draw_val()
# -*- coding: utf-8 -*-
import math
from PyQt5.QtCore import QObject, QSize, QPointF, Qt, QRect, QPoint
from PyQt5.QtGui import QPainter, QColor, QPen, QRadialGradient, QBrush, QPolygon, QFont, QPainterPath
from AbstractMeter import AbstractMeter
class TacoMeterPrivate(QObject):
def __init__(self, q):
QObject.__init__(self)
self.mPointer = q
self.mDigitFont = QFont()
self.mDigitFont.setPointSizeF(18)
self.mValueFont = QFont()
self.mValueFont.setPointSizeF(22)
self.mDigitOffset = 105.0
self.mValueOffset = -100
def draw_background(self, painter):
self.initCoordinateSystem(painter)
pen = QPen(QColor(0, 0, 0))
pen.setWidth(4)
painter.setPen(pen)
back1 = QRadialGradient(QPointF(0.0, 0.0), 180.0, QPointF(-35.0, 145.0))
back1.setColorAt(0.0, QColor(250, 250, 250))
back1.setColorAt(1.0, QColor(20, 20, 20))
back2 = QRadialGradient(QPointF(0.0, 0.0), 225.0, QPointF(76.5, 135.0))
back2.setColorAt(0.0, QColor(10, 10, 10))
back2.setColorAt(1.0, QColor(250, 250, 250))
painter.setBrush(QBrush(back1))
painter.drawEllipse(-162, -162, 324, 324);
painter.setPen(Qt.NoPen)
painter.setBrush(QBrush(back2))
painter.drawEllipse(-152, -152, 304, 304)
shield = QRadialGradient(QPointF(0, 0), 182, QPointF(-12.0, -15.0))
shield.setColorAt(0.0, Qt.white)
shield.setColorAt(0.5, QColor(240, 240, 240))
shield.setColorAt(1.0, QColor(215, 215, 215))
painter.setBrush(QBrush(shield))
painter.setPen(pen)
painter.drawEllipse(-142, -142, 284, 284)
painter.setPen(Qt.NoPen)
painter.setBrush(QColor(0, 200, 0))
angle = int((3840 * (self.mPointer.nominal() - self.mPointer.minimal())) / (
self.mPointer.maximal() - self.mPointer.minimal()))
painter.drawPie(QRect(-141, -141, 282, 282), -480, 3840 - angle % 5760)
painter.setBrush(QBrush(Qt.red))
angle = int((3840 * (self.mPointer.critical() - self.mPointer.minimal())) / (
self.mPointer.maximal() - self.mPointer.minimal()))
painter.drawPie(QRect(-141, -141, 282, 282), -480, 3840 - angle % 5760)
painter.setBrush(QBrush(shield))
painter.drawEllipse(-129, -129, 258, 258)
painter.rotate(60)
painter.save()
painter.setBrush(QBrush(Qt.black))
line_length = 10
scaleTriangle = [QPoint(-6, 141), QPoint(6, 141), QPoint(0, 129)]
for i in range(33):
painter.setPen(pen)
if i % 4:
painter.drawLine(0, 140, 0, 140 - line_length)
else:
painter.setPen(Qt.NoPen)
painter.drawConvexPolygon(QPolygon(scaleTriangle))
painter.rotate(7.5)
pen.setWidth(3)
if i % 2:
line_length = 10
else:
line_length = 5
painter.restore()
painter.setPen(Qt.black)
painter.rotate(-60.0)
painter.setFont(self.mDigitFont)
for i in range(9):
v = self.mPointer.minimal() + i * (self.mPointer.maximal() - self.mPointer.minimal()) / 8.0
if abs(v) < 0.000001:
v = 0.0
val = "{}".format(v)
Size = painter.fontMetrics().size(Qt.TextSingleLine, val)
painter.save()
painter.translate(self.mDigitOffset * math.cos((5 + i) * math.pi / 6.0),
self.mDigitOffset * math.sin((5 + i) * math.pi / 6.0))
painter.drawText(QPointF(Size.width() / -2.0, Size.height() / 4.0), val)
painter.restore()
def draw_value(self, painter):
self.initCoordinateSystem(painter)
hand = [-4, 0, -1, 129, 1, 129, 4, 0, 8, -50, -8, -50]
hand_path = QPainterPath()
hand_path.moveTo(QPointF(hand[0], hand[1]))
for i in range(2, 10, 2):
hand_path.lineTo(hand[i], hand[i + 1])
hand_path.cubicTo(8.1, -51.0, 5.0, -48.0, 0.0, -48.0)
hand_path.cubicTo(-5.0, -48.0, -8.1, -51.0, -8.0, -50.0)
painter.save()
painter.rotate(60.0)
painter.setPen(Qt.NoPen)
painter.setBrush(QBrush(Qt.black))
painter.rotate(((self.mPointer.value() -
self.mPointer.minimal()) * 240.0) / (self.mPointer.maximal() - self.mPointer.minimal()))
painter.drawPath(hand_path)
painter.drawEllipse(-10, -10, 20, 20)
painter.restore()
if self.mPointer.value() >= self.mPointer.critical():
painter.setPen(Qt.red)
painter.setFont(self.mValueFont)
st = "{0:.4g} %".format(self.mPointer.value())
Size = painter.fontMetrics().size(Qt.TextSingleLine, st)
painter.drawText(QPointF(Size.width() / -2, -self.mValueOffset), st)
painter.end()
def initCoordinateSystem(self, painter):
side = min(self.mPointer.width(), self.mPointer.height())
painter.setRenderHint(QPainter.Antialiasing)
painter.translate(self.mPointer.width() / 2, self.mPointer.height() / 2)
painter.scale(side / 335.0, side / 335.0)
class TacoMeter(AbstractMeter):
def __init__(self, parent=None):
AbstractMeter.__init__(self, parent=parent)
self.dPtr = TacoMeterPrivate(self)
self.value_background = False
def sizeHint(self):
return QSize(300, 300)
def draw_background(self, painter):
self.dPtr.draw_background(painter)
def draw_value(self, painter):
self.dPtr.draw_value(painter)
if __name__ == '__main__':
import sys
import random
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import QTimer
app = QApplication(sys.argv)
w = TacoMeter()
timer = QTimer()
timer.timeout.connect(lambda : w.setValue(random.uniform(0, 100)))
timer.start(1000)
w.show()
sys.exit(app.exec_())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment