Частично заполненный эллипс - PullRequest
0 голосов
/ 24 ноября 2018

В настоящее время я рисую эллипсы на GraphicScene:

pen = QtGui.QPen(QtGui.QColor(QtCore.Qt.lightGray).darker(50))
for id, light in arrLights.iteritems():
    angle = i*delta
    circX = (w + x) * math.cos(angle)
    circY = (h + y) * math.sin(angle)
    item = callbackEllipse(light, hiveLight, circX, circY, w, h)
    item.setAcceptHoverEvents(True)
    item.setPen(pen)

    if (light["status"]):
        brush = QtGui.QBrush(QtGui.QColor(QtCore.Qt.lightGray))
    else:
        brush = QtGui.QBrush(QtGui.QColor(QtCore.Qt.lightGray).darker(150))

    item.setBrush(brush)
    self.scene().addItem(item)
    self.writeText(light['name'], circX , circY, w, h)
    i = i + 1

(callbackEllipse - это класс с родительским классом QGraphicsEllipseItem для событий щелчка мыши)

Я пытаюсь понять, какЯ могу частично заполнить эти эллипсы (в процентах), как на следующих изображениях:

Эллипс

Эллипс

Эллипс

Я искал и пробовал несколько вещей, таких как множественные эллипсы и нарисованные пути, но это повлияло на события щелчка, и я потерял границу«незаполненная» часть эллипса.

Кто-нибудь может помочь?

1 Ответ

0 голосов
/ 24 ноября 2018

Для этих случаев необходимо реализовать пользовательский элемент и перезаписать метод рисования, используйте QGraphicsEllipseItem в качестве основы, так как достаточно добавить процентные свойства и цвет заливки, если вы хотите, чтобы он был перекрашен, вы должны вызвать update().Для рисования создайте 2 QPixmaps, сначала нарисуйте прямоугольник, а затем эллипс, затем соедините их с помощьюpositionMode

from PyQt5 import QtCore, QtGui, QtWidgets

class CallbackEllipse(QtWidgets.QGraphicsEllipseItem):
    def __init__(self, light, *args, **kwargs):
        super(CallbackEllipse, self).__init__(*args, **kwargs)
        self._fill_brush = QtGui.QBrush(QtCore.Qt.NoBrush)
        self._percentage = 0
        self._light = light

    def setFillBrush(self, brush):
        self._fill_brush = brush
        self.update()

    def fillBrush(self):
        return self._fill_brush

    def setPercentage(self, percentage):
        self._percentage = percentage
        self.update()

    def percentage(self):
        return self._percentage

    def paint(self, painter, option, widget=None):
        painter.setPen(self.pen())
        r_in = QtCore.QRectF(QtCore.QPointF(), self.rect().size())
        r_out = QtCore.QRectF(r_in)
        r_out.setTop((1-self.percentage())*r_in.height())

        p1 = QtGui.QPixmap(r_in.size().toSize())
        p1.fill(QtCore.Qt.transparent)
        p_1 = QtGui.QPainter(p1)
        p_1.setRenderHints(painter.renderHints())
        p_1.fillRect(r_out, self.fillBrush())
        p_1.end()

        p2 = QtGui.QPixmap(r_in.size().toSize())
        p2.fill(QtCore.Qt.transparent)
        p_2 = QtGui.QPainter(p2)
        p_2.setRenderHints(painter.renderHints())
        p_2.setPen(painter.pen())
        p_2.setBrush(self.brush())
        p_2.drawEllipse(r_in)
        p_2.end()

        pixmap = QtGui.QPixmap(r_in.size().toSize())
        pixmap.fill(QtCore.Qt.transparent)
        p = QtGui.QPainter(pixmap)
        p.setRenderHints(painter.renderHints())
        p.drawPixmap(QtCore.QPointF(), p1)
        p.setCompositionMode(QtGui.QPainter.CompositionMode_DestinationAtop)
        p.drawPixmap(QtCore.QPointF(), p2)
        p.end()

        painter.drawPixmap(option.rect.topLeft(), pixmap)
        painter.setPen(self.pen())
        painter.drawEllipse(option.rect)

class GraphicsView(QtWidgets.QGraphicsView):
    def __init__(self, parent=None):
        super(GraphicsView, self).__init__(parent)
        self.setScene(QtWidgets.QGraphicsScene(self))
        self.setRenderHints(self.renderHints() | QtGui.QPainter.Antialiasing)
        light = {"status": True, "name": "myname"}
        it = CallbackEllipse(light, 100, 100, 100, 100)
        it.setPercentage(0.4)
        it.setPen(QtGui.QPen(QtGui.QColor(QtCore.Qt.lightGray).darker(150)))
        it.setBrush(QtGui.QBrush(QtGui.QColor(QtCore.Qt.white)))
        it.setFillBrush(QtGui.QBrush(QtGui.QColor("#4471C4")))
        self.scene().addItem(it)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = GraphicsView()
    w.resize(640, 480)
    w.show()
    sys.exit(app.exec_())

enter image description here

...