【问题标题】:How to create a "Color Circle" in PyQt?如何在 PyQt 中创建“色环”?
【发布时间】:2018-06-06 12:43:27
【问题描述】:

我想创建一个如下所示的 QWidget/QDialog:

Color Circle
或:
Windows Color Picker

我知道QColorDialog,但我不想使用它。

【问题讨论】:

    标签: python python-3.x pyqt pyqt5


    【解决方案1】:

    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()
    

    输出:

    【讨论】:

      【解决方案2】:

      我知道这是一个老问题,
      但由于唯一的答案性能很差,这是我的版本。 它使用两个相互叠加的渐变,而不是单独渲染小部件中的每个点。

      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())
      

      可以在此 gist https://gist.github.com/tobi08151405/7b0a8151c9df1a41a87c1559dac1243a 找到功能齐全的版本(带有信号、设置/获取功能)

      【讨论】:

        猜你喜欢
        • 2022-01-25
        • 1970-01-01
        • 2014-09-02
        • 1970-01-01
        • 2016-10-06
        • 1970-01-01
        • 2017-05-10
        • 2012-12-13
        • 1970-01-01
        相关资源
        最近更新 更多