Skip to content

Instantly share code, notes, and snippets.

@MaurizioB
Last active June 11, 2021 13:57
Show Gist options
  • Save MaurizioB/1d4a10112fbf9b63f035ccea98ff7e29 to your computer and use it in GitHub Desktop.
Save MaurizioB/1d4a10112fbf9b63f035ccea98ff7e29 to your computer and use it in GitHub Desktop.
Simple QDial subclass with paint event override
from PyQt5 import QtCore, QtGui, QtWidgets
class SimpleDial(QtWidgets.QDial):
def paintEvent(self, event):
# create a QStyleOption for the dial, and initialize it with the basic properties
# that will be used for the configuration of the painter
opt = QtWidgets.QStyleOptionSlider()
self.initStyleOption(opt)
# construct a QRectF that uses the minimum between width and height,
# and adds some margins for better visual separation
# this is partially taken from the fusion style helper source
width = opt.rect.width()
height = opt.rect.height()
r = min(width, height) / 2
r -= r / 50
d_ = r / 6
dx = opt.rect.x() + d_ + (width - 2 * r) / 2 + 1
dy = opt.rect.y() + d_ + (height - 2 * r) / 2 + 1
br = QtCore.QRectF(dx + .5, dy + .5,
int(r * 2 - 2 * d_ - 2),
int(r * 2 - 2 * d_ - 2))
penColor = self.palette().dark().color()
qp = QtGui.QPainter(self)
qp.setRenderHints(qp.Antialiasing)
qp.setPen(QtGui.QPen(penColor, 4))
qp.drawEllipse(br)
# find the "real" value ratio between minimum and maximum
realValue = (self.value() - self.minimum()) / (self.maximum() - self.minimum())
# compute the angle at which the dial handle should be placed, assuming
# a range between 240° and 300° (moving clockwise)
angle = 240 - 300 * realValue
# create a polar line for the position of the handle; this can also
# be done using the math module with some performance improvement
line = QtCore.QLineF.fromPolar(r * .6, angle)
line.translate(br.center())
ds = r / 5
# create the handle rect and position it at the end of the polar line
handleRect = QtCore.QRectF(0, 0, ds, ds)
handleRect.moveCenter(line.p2())
qp.setPen(QtGui.QPen(penColor, 2))
qp.drawEllipse(handleRect)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
dial = SimpleDial()
dial.show()
sys.exit(app.exec_())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment