Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different colours in an arc

Consider the following toy example:

from PyQt5 import QtWidgets, QtGui, QtCore

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()

        w = QtWidgets.QWidget()
        layout = QtWidgets.QVBoxLayout()
        w.setLayout(layout)
        self.setCentralWidget(w)

        label = QtWidgets.QLabel()
        canvas = QtGui.QPixmap(400, 300)
        label.setPixmap(canvas)
        layout.addWidget(label)

        def paintEvent():
            painter = QtGui.QPainter(label.pixmap())
            painter.setRenderHint(QtGui.QPainter.Antialiasing)
            painter.setPen(QtCore.Qt.red)
            painter.drawArc(0, 0, 100, 100, 1440, -2880)
            painter.end()

        paintEvent()

        self.show()

app = QtWidgets.QApplication([])
window = MainWindow()
app.exec_()

How can I paint the arc using an arbitrary number of colours ideally of varying lengths?

I tried to do it with gradients (linear and conical) but I have been unable to obtain accurate results.

I suppose the broader question is can I somehow have different pen colours when painting an arc? Note that the arc can be a half circle, a full circle or anything in between.

The colours are to be distributed using percentages. Each colour is a fraction of the arc's length. But I am content with a solution where all colours are equally spaced.

like image 882
Giuseppe Avatar asked Jan 31 '26 22:01

Giuseppe


1 Answers

A possible solution is to paint the arc in parts:

from PyQt5 import QtCore, QtGui, QtWidgets


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()

        w = QtWidgets.QWidget()
        layout = QtWidgets.QVBoxLayout()
        w.setLayout(layout)
        self.setCentralWidget(w)

        label = QtWidgets.QLabel()
        canvas = QtGui.QPixmap(400, 300)
        canvas.fill(QtGui.QColor("white"))
        label.setPixmap(canvas)
        layout.addWidget(label)

        def paint_label():
            painter = QtGui.QPainter(label.pixmap())
            painter.setRenderHint(QtGui.QPainter.Antialiasing)
            r = QtCore.QRect(0, 0, 100, 100)
            delta_angle = -180 * 16
            start_angle = 90 * 16
            values = (1, 2, 3, 4)
            colors = (
                QtGui.QColor("red"),
                QtGui.QColor("blue"),
                QtGui.QColor("green"),
                QtGui.QColor("yellow"),
            )
            sum_of_values = sum(values)
            for value, color in zip(values, colors):
                end_angle = start_angle + int((value/sum_of_values) * delta_angle)
                painter.setPen(color)
                painter.drawArc(r, start_angle, end_angle - start_angle)
                start_angle = end_angle
            painter.end()

        paint_label()

        self.show()


def main():

    app = QtWidgets.QApplication([])
    window = MainWindow()
    app.exec_()


if __name__ == "__main__":
    main()
like image 138
eyllanesc Avatar answered Feb 02 '26 10:02

eyllanesc