高级渐变

Advanced gradient

我正在尝试制作简单的颜色选择器。一开始,它由 r、g、b 和 h、s、l 滑块组成,但后来我决定使用更常见的选择器,带有色相滑块的那个和这张图片中的东西

这是我第一次处理 colors/gradients 并尝试用 qlineargradient 制作东西并实现渐变,但意识到渐变不是这样工作的。我不确定如何以编程方式绘制图片中的渐变。我怎样才能画出类似的东西?我说的不是颜色选择器本身,而是图像中的渐变。

以下是我试过的;

import sys
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
import pathlib
import customColorsList


class widget(QWidget):
    def __init__(self):
        super(widget, self).__init__()

        self.resize(300, 300)

        self.setStyleSheet("background: qlineargradient("
                           "x1:0, y1:0,"
                           "x2:1, y2:1,"
                           "stop:0 white,"
                           "stop:0.5 green,"
                           "stop:1 black);")


if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = widget()
    w.show()
    sys.exit(app.exec_())  

你无法使用简单的渐变来实现,但是你可以使用基本的组合,水平的 QLinearGradient 用于颜色,垂直的用于黑色分量。

基本概念是这样的:

        self.gradient = QtGui.QLinearGradient(0, 0, 1, 0)
        self.gradient.setCoordinateMode(QtGui.QGradient.ObjectBoundingMode)
        self.gradient.setColorAt(0, QtCore.Qt.white)
        self.gradient.setColorAt(0, QtCore.Qt.green)

        self.overlay = QtGui.QLinearGradient(0, 0, 0, 1)
        self.overlay.setCoordinateMode(QtGui.QGradient.ObjectBoundingMode)
        self.overlay.setColorAt(0, QtCore.Qt.transparent)
        self.overlay.setColorAt(1, QtCore.Qt.black)

在下面的例子中,我实现了一个基本的小部件来显示颜色和一个简单的界面来改变它:

from PyQt5 import QtCore, QtGui, QtWidgets

class Picker(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setMinimumSize(250, 250)

        self.gradient = QtGui.QLinearGradient(0, 0, 1, 0)
        self.gradient.setCoordinateMode(QtGui.QGradient.ObjectBoundingMode)
        self.gradient.setColorAt(0, QtCore.Qt.white)

        self.overlay = QtGui.QLinearGradient(0, 0, 0, 1)
        self.overlay.setCoordinateMode(QtGui.QGradient.ObjectBoundingMode)
        self.overlay.setColorAt(0, QtCore.Qt.transparent)
        self.overlay.setColorAt(1, QtCore.Qt.black)

    def setColor(self, color):
        self.gradient.setColorAt(1, color)
        self.update()

    def paintEvent(self, event):
        qp = QtGui.QPainter(self)
        qp.fillRect(self.rect(), self.gradient)
        qp.fillRect(self.rect(), self.overlay)


class Test(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        layout = QtWidgets.QVBoxLayout(self)
        self.picker = Picker()
        layout.addWidget(self.picker)
        self.redSlider = QtWidgets.QSlider(QtCore.Qt.Horizontal, maximum=255)
        layout.addWidget(self.redSlider)
        self.greenSlider = QtWidgets.QSlider(QtCore.Qt.Horizontal, maximum=255)
        layout.addWidget(self.greenSlider)
        self.blueSlider = QtWidgets.QSlider(QtCore.Qt.Horizontal, maximum=255)
        layout.addWidget(self.blueSlider)

        self.redSlider.valueChanged.connect(self.updateColor)
        self.greenSlider.valueChanged.connect(self.updateColor)
        self.blueSlider.valueChanged.connect(self.updateColor)

        self.setColor(QtGui.QColor(QtCore.Qt.green))

    def setColor(self, color):
        self.redSlider.blockSignals(True)
        self.redSlider.setValue(color.red())
        self.redSlider.blockSignals(False)

        self.greenSlider.blockSignals(True)
        self.greenSlider.setValue(color.green())
        self.greenSlider.blockSignals(False)

        self.blueSlider.blockSignals(True)
        self.blueSlider.setValue(color.blue())
        self.blueSlider.blockSignals(False)

        self.updateColor()

    def updateColor(self):
        color = QtGui.QColor(
            self.redSlider.value(), 
            self.greenSlider.value(), 
            self.blueSlider.value()
            )
        self.picker.setColor(color)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    test = Test()
    test.show()
    sys.exit(app.exec_())