4

带静态梯度指示器的表盘

所以我有这个用于 PyQt 小部件的表盘图像。现在,如您所见,渐变指示器,绿-黄-红弧是静态的,是图像的一部分。

我想动态创建它,以便根据某些范围确定颜色。例如,不是等量的绿色和红色,我可能希望大约 60 度的值是红色,其余部分是绿色和黄色。为此,我将指定一些范围(例如,0-90 度应该是绿色等)。

关于如何绘制这种 CURVED 颜色渐变的任何想法?

4

1 回答 1

7

要做到这一点,一种方法是创建一个小部件并执行一个自定义的paintEvent。您将使用几个元素构建此结果:

  1. 绘制仪表背景的静态像素图
  2. 绘制带有渐变的饼形
  3. 用原始图像重新填充中心以再次将其剪掉

您将需要在 init 中缓存一次像素图,这样您就不会继续从磁盘创建它。然后你可以给小部件一个方法来设置值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)

季度值

半价

全值

您可以通过公开一种设置颜色的方法甚至更改开始和结束范围来进一步扩展此小部件。它们将是 paintEvent 将引用的属性,就像它现在使用的 value 属性一样。

您还可以调整色标值以更改范围的平衡。

确保让paintEvent 进行尽可能少的处理。

于 2012-08-19T20:36:07.387 回答