これを実現する1つの方法は、ウィジェットを作成してカスタムのpaintEventを実行することです。この結果は、いくつかの要素で構築されます。
- ゲージの背景の静的なピックスマップを描画します
- グラデーションでパイの形を描く
- 中央に元の画像を再入力して、もう一度切り取ります
ピックスマップをディスクから作成し続けないように、初期化で一度キャッシュする必要があります。次に、ウィジェットにから値を設定するメソッドを与えることができます0.0 - 1.0
。
class GaugeWidget(QtGui.QWidget):
def __init__(self, initialValue=0, *args, **kwargs):
super(GaugeWidget, self).__init__(*args, **kwargs)
self._bg = QtGui.QPixmap("bg.png")
self.setValue(initialValue)
def setValue(self, val):
val = float(min(max(val, 0), 1))
self._value = -270 * val
self.update()
def paintEvent(self, event):
painter = QtGui.QPainter(self)
painter.setRenderHint(painter.Antialiasing)
rect = event.rect()
gauge_rect = QtCore.QRect(rect)
size = gauge_rect.size()
pos = gauge_rect.center()
gauge_rect.moveCenter( QtCore.QPoint(pos.x()-size.width(), pos.y()-size.height()) )
gauge_rect.setSize(size*.9)
gauge_rect.moveCenter(pos)
refill_rect = QtCore.QRect(gauge_rect)
size = refill_rect.size()
pos = refill_rect.center()
refill_rect.moveCenter( QtCore.QPoint(pos.x()-size.width(), pos.y()-size.height()) )
# smaller than .9 == thicker gauge
refill_rect.setSize(size*.9)
refill_rect.moveCenter(pos)
painter.setPen(QtCore.Qt.NoPen)
painter.drawPixmap(rect, self._bg)
painter.save()
grad = QtGui.QConicalGradient(QtCore.QPointF(gauge_rect.center()), 270.0)
grad.setColorAt(.75, QtCore.Qt.green)
grad.setColorAt(.5, QtCore.Qt.yellow)
grad.setColorAt(.25, QtCore.Qt.red)
painter.setBrush(grad)
painter.drawPie(gauge_rect, 225.0*16, self._value*16)
painter.restore()
painter.setBrush(QtGui.QBrush(self._bg.scaled(rect.size())))
painter.drawEllipse(refill_rect)
super(GaugeWidget,self).paintEvent(event)



色を設定する方法を公開したり、開始範囲と終了範囲を変更したりすることで、このウィジェットをさらに拡張できます。これらは、現在使用しているvalue属性と同様に、paintEventが参照する属性になります。
カラーストップ値を調整して、範囲のバランスを変更することもできます。
paintEventの処理をできるだけ少なくするようにしてください。