【问题标题】:PyQt creating color circlePyQt 创建色环
【发布时间】:2022-01-25 00:20:12
【问题描述】:

我想在小部件占位符中添加一个色环:

我已经尝试过这个库: https://gist.github.com/tobi08151405/7b0a8151c9df1a41a87c1559dac1243a

但如果窗口不是样方,色环就不起作用。 我已经尝试过其他解决方案,但是没有办法获取颜色值。 How to create a "Color Circle" in PyQt?

您能否推荐/告诉我一种创建自己的方法,以便我可以将它们添加到那里? 谢谢!

【问题讨论】:

    标签: pyqt pyqt5 qt-designer


    【解决方案1】:

    小部件假定它的形状始终是正方形;该代码为此提供了一个自定义AspectLayout,但这不是必需的。

    问题在于,当形状不是正方形时,颜色的计算是错误的,因为当一个维度比另一个维度大得多时,坐标没有正确映射。例如,如果小部件比高度宽得多,x 坐标会“移动”,因为圆(现在是实际的椭圆)显示为居中,但颜色函数使用 最小 大小。

    解决方案是创建一个始终显示在中心的内部QRect,并将其用于绘制计算:

    class ColorCircle(QWidget):
        # ...
        def resizeEvent(self, ev: QResizeEvent) -> None:
            size = min(self.width(), self.height())
            self.radius = size / 2
            self.square = QRect(0, 0, size, size)
            self.square.moveCenter(self.rect().center())
    
        def paintEvent(self, ev: QPaintEvent) -> None:
            # ...
            p.setPen(Qt.transparent)
            p.setBrush(hsv_grad)
            p.drawEllipse(self.square)
            p.setBrush(val_grad)
            p.drawEllipse(self.square)
            # ...
    
        def map_color(self, x: int, y: int) -> QColor:
            x -= self.square.x()
            y -= self.square.y()
            # ...
    

    请注意,该代码使用 numpy,但它用于那些显然不需要 numpy 性能的应用程序真正需要这样一个 huge 库的函数。

    例如,line_circle_inter 使用一种复杂的方法来计算“光标”(小圆圈)的位置,但这绝对没有必要,因为色相和饱和度值已经提供了“可用”坐标:色相表示圆中的角度(从 12 小时位置开始,逆时针方向),而饱和度是到中心的距离。
    QLineF 提供了一个方便的函数fromPolar(),它返回一条具有给定长度和角度的线:长度将是半径乘以饱和度,角度是色相乘以 360(加上 90°,因为角度总是从3点);然后我们可以在圆的中心平移那条线,光标将定位在线段的第二个点:

        def paintEvent(self, event):
            # ...
            p.setPen(Qt.black)
            p.setBrush(self.selected_color)
            line = QLineF.fromPolar(self.radius * self.s, 360 * self.h + 90)
            line.translate(self.square.center())
            p.drawEllipse(line.p2(), 10, 10)
    

    地图颜色函数可以使用相同的逻辑,但是颠倒:我们从中心开始构建一条线到鼠标光标位置,然后饱和度是长度除以半径(将值清理为1.0,如这是最大可能值),而色调是线角度(如上减 90°)除以 360 并针对正值0.0-1.0 范围进行了清理。

        def map_color(self, x: int, y: int) -> QColor:
            line = QLineF(QPointF(self.rect().center()), QPointF(x, y))
            s = min(1.0, line.length() / self.radius)
            h = (line.angle() - 90) / 360 % 1.
            return h, s, self.v
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-12
      • 1970-01-01
      • 1970-01-01
      • 2016-10-06
      • 2015-09-21
      • 1970-01-01
      • 1970-01-01
      • 2021-02-19
      相关资源
      最近更新 更多