PyotrK
PyotrK

Reputation: 29

How to create a "Color Circle" in PyQt?

I would like to create a QWidget/QDialog that looks like this:

Color Circle
or:
Windows Color Picker

I am aware of QColorDialog, but i do not want to use it.

Upvotes: 1

Views: 3548

Answers (2)

Tobi Tei
Tobi Tei

Reputation: 51

I know this is a old question,
but since the only answer has pretty bad performance, here is my version. It uses two gradients laid on top of each other instead of rendering each point in the widget separately.

class ColorCircle(QWidget):

    def __init__(self, parent=None) -> None:
        super().__init__(parent=parent)
        self.radius = 0

    def resizeEvent(self, ev: QResizeEvent) -> None:
        self.radius = min([self.width()/2, self.height()/2])

    def paintEvent(self, ev: QPaintEvent) -> None:
        center = QPointF(self.width()/2, self.height()/2)
        p = QPainter(self)
        hsv_grad = QConicalGradient(center, 90)
        for deg in range(360):
            col = QColor.fromHsvF(deg / 360, 1, self.v)
            hsv_grad.setColorAt(deg / 360, col)

        val_grad = QRadialGradient(center, self.radius)
        val_grad.setColorAt(0.0, QColor.fromHsvF(0.0, 0.0, self.v, 1.0))
        val_grad.setColorAt(1.0, Qt.transparent)

        p.setPen(Qt.transparent)
        p.setBrush(hsv_grad)
        p.drawEllipse(self.rect())
        p.setBrush(val_grad)
        p.drawEllipse(self.rect())

a fully functional version (with signals, set/get functions) can be found at this gist https://gist.github.com/tobi08151405/7b0a8151c9df1a41a87c1559dac1243a

Upvotes: 5

Jonas
Jonas

Reputation: 1847

HSV Color Space

from PyQt5 import QtWidgets, QtCore, QtGui
import sys
import numpy as np

class ColorCircle(QtWidgets.QWidget):

    def __init__(self):
        super().__init__()
        self.radius = 100.
        self.setFixedSize(200, 200)

    def paintEvent(self, ev):
        super().paintEvent(ev)
        p = QtGui.QPainter(self)
        for i in range(self.width()):
            for j in range(self.height()):
                color = QtGui.QColor(255, 255, 255, 255)
                h = (np.arctan2(i-self.radius, j-self.radius)+np.pi)/(2.*np.pi)
                s = np.sqrt(np.power(i-self.radius, 2)+np.power(j-self.radius, 2))/self.radius
                v = 1.0
                if s < 1.0:
                    color.setHsvF(h, s, v, 1.0)
                p.setPen(color)
                p.drawPoint(i, j)

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    w = ColorCircle()
    w.show()
    app.exec()

Output:

color wheel

Upvotes: 3

Related Questions