Home>

Out in the openstackoverflowfound an example withQColorDialogto PyQt5 .
I wanted to add to my application, but I want to cut from thiscolor_dialogeverything is unnecessary.

I want to leave only the color picker where you can move the cursor and select a color.

See example below. How can this be done? A window with only this palette should open.

from PyQt5 import QtCore, QtGui, QtWidgets
class MainWindow (QtWidgets.QMainWindow):
    def __init __ (self, parent= None):
        super (MainWindow, self) .__ init __ (parent)
        central_widget= QtWidgets.QWidget ()
        self.setCentralWidget (central_widget)
        button= QtWidgets.QPushButton ("Open QColorDialog")
        self.label= QtWidgets.QLabel ("Background", alignment= QtCore.Qt.AlignCenter)
        self.label.setAutoFillBackground (True)
        lay= QtWidgets.QVBoxLayout (central_widget)
        lay.addWidget (button)
        lay.addWidget (self.label)
        self.color_dialog= QtWidgets.QColorDialog (self)
        self.color_dialog.currentColorChanged.connect (self.on_currentColorChanged)
        button.clicked.connect (self.color_dialog.show)
    @ QtCore.pyqtSlot (QtGui.QColor)
    def on_currentColorChanged (self, color):
        pal= self.label.palette ()
        pal.setColor (QtGui.QPalette.Background, color)
        self.label.setPalette (pal)
if __name__== '__main__':
    import sys
    app= QtWidgets.QApplication (sys.argv)
    w= MainWindow ()
    w.resize (640, 480)
    w.show ()
    sys.exit (app.exec_ ())
  • Answer # 1

    Alternatively, comments in the example text.

    import sys
    from PyQt5 import QtCore, QtGui, QtWidgets
    class RgbPicker (QtWidgets.QLabel):
        # create a vertical color gradient similar to `Color Shower`,
        # used in QColorDialog
        colorGrads= QtGui.QLinearGradient (0, 0, 1, 0)
        colorGrads.setCoordinateMode (colorGrads.ObjectBoundingMode)
        xRatio= 1. /6
        colorGrads.setColorAt (0, QtCore.Qt.red)
        colorGrads.setColorAt (1, QtCore.Qt.red)
        colorGrads.setColorAt (xRatio, QtCore.Qt.magenta)
        colorGrads.setColorAt (xRatio * 2, QtCore.Qt.blue)
        colorGrads.setColorAt (xRatio * 3, QtCore.Qt.cyan)
        colorGrads.setColorAt (xRatio * 4, QtCore.Qt.green)
        colorGrads.setColorAt (xRatio * 5, QtCore.Qt.yellow)
        # add a `mask` gradient to support gradients for lighter colors
        maskGrad= QtGui.QLinearGradient (0, 0, 0, 1)
        maskGrad.setCoordinateMode (maskGrad.ObjectBoundingMode)
        maskGrad.setColorAt (0, QtCore.Qt.transparent)
        maskGrad.setColorAt (1, QtCore.Qt.white)
        # create a cross cursor to show the selected color
        cursorPath= QtGui.QPainterPath ()
        cursorPath.moveTo (-10, 0)
        cursorPath.lineTo (-4, 0)
        cursorPath.moveTo (0, -10)
        cursorPath.lineTo (0, -4)
        cursorPath.moveTo (4, 0)
        cursorPath.lineTo (10, 0)
        cursorPath.moveTo (0, 4)
        cursorPath.lineTo (0, 10)
        cursorPen= QtGui.QPen (QtCore.Qt.black, 3)
        colorChanged= QtCore.pyqtSignal (QtGui.QColor)
        showCursor= False
        cursorPos= QtCore.QPoint ()
        def __init __ (self, parent= None):
            super () .__ init __ (parent)
            self.setMouseTracking (True)
            self.setFixedSize (220, 200)
            # create a bitmap and paint over it with gradients
            pixmap= QtGui.QPixmap (self.size ())
            qp= QtGui.QPainter (pixmap)
            qp.fillRect (pixmap.rect (), self.colorGrads)
            qp.fillRect (pixmap.rect (), self.maskGrad)
            qp.end ()
            self.setPixmap (pixmap)
            # QImage is required to get the color of a specific pixel
            self.image= pixmap.toImage ()
            self.currentColor= QtGui.QColor ()
        def setColor (self, color):
            self.currentColor= color
            # calculate the coordinates of the cursor according to the color values;
            # this is based on the Hue /Saturation /Value data of the color
            h, s, v, a= color.getHsv ()
            x= (360 -h) * (self.width () -1) /360.
            y= (255 -s) * (self.height () -1) /255.
            self.cursorPos= QtCore.QPoint (x, y)
            self.showCursor= True
            self.update ()
        def mousePressEvent (self, event):
            if event.button ()== QtCore.Qt.LeftButton:
                # set current color and emit colorChanged signal
                self.currentColor= QtGui.QColor (self.image.pixel (event.pos ()))
                self.cursorPos= event.pos ()
                self.showCursor= True
                self.update ()
        def mouseMoveEvent (self, event):
            if event.pos () in self.rect ():
                color= QtGui.QColor (self.image.pixel (event.pos ()))
                self.colorChanged.emit (color)
                if event.buttons ()== QtCore.Qt.LeftButton:
                    # if the left button is pressed, update the current color
                    self.currentColor= color
                    self.cursorPos= event.pos ()
                    self.update ()
        def leaveEvent (self, event):
            # emit previously selected color on exit
            self.colorChanged.emit (self.currentColor)
        def paintEvent (self, event):
            # paint the "color shower"
            QtWidgets.QLabel.paintEvent (self, event)
            if self.showCursor:
                # paint the color "cursor"
                qp= QtGui.QPainter (self)qp.setPen (self.cursorPen) qp.translate (self.cursorPos)
                qp.drawPath (self.cursorPath)
    class ColorPicker (QtWidgets.QDialog):
        colorChanged= QtCore.pyqtSignal (QtGui.QColor)
        def __init __ (self, parent= None):
            super () .__ init __ (parent)
            self.setGeometry (650, 100, 240, 250)
            layout= QtWidgets.QVBoxLayout ()
            self.setLayout (layout)
            self.rgbPicker= RgbPicker (self)
            layout.addWidget (self.rgbPicker)
            self.rgbPicker.colorChanged.connect (self.colorChanged)
            buttonBox= QtWidgets.QDialogButtonBox (QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel)
            layout.addWidget (buttonBox)
            buttonBox.accepted.connect (self.accept)
            buttonBox.rejected.connect (self.reject)
        def getColor (self, color= None):
            if isinstance (color, QtGui.QColor):
                self.rgbPicker.setColor (color)
            # return color only if dialog is accepted
            if self.exec_ ():
                return self.rgbPicker.currentColor
    class MainWindow (QtWidgets.QWidget):
        def __init __ (self):
            super () .__ init __ ()
            # get the current background color, we must ignore the picker selection
            self.color= self.palette (). color (QtGui.QPalette.Window)
            self.colorPicker= ColorPicker (self)
            self.colorPicker.colorChanged.connect (self.setcolorChanged)
            self.colorChooser= QtWidgets.QPushButton ("ColorChooser", self)
            self.colorChooser.clicked.connect (self.onColorPicker)
            self.colorChooser.move (10, 10)
        def setcolorChanged (self, color):
            # set the stylesheet to `only` for this class, not its descendants,
            # otherwise you set the background for the `and` button of the color picker
            self.setStyleSheet ("MainWindow {background-color:% s;}"% color.name ())
        def onColorPicker (self):
            color= self.colorPicker.getColor (self.color)
            # update the color only if the dialog is accepted:
            # if the user presses the `Esc` key, it will be ignored
            if color:
                print ('ok', color.getRgb ())
                self.color= color
            self.setcolorChanged (self.color)
    if __name__== '__main__':
        app= QtWidgets.QApplication (sys.argv)
        w= MainWindow ()
        w.setGeometry (350, 100, 243, 253)
        w.show ()
        sys.exit (app.exec_ ())
    

    It's amazing! I will disassemble the code and do the task for myself -to change the shape of all this to make it look more beautiful.

    imapw_2021-09-27 10:52:23
  • Answer # 2

    Alternatively, comments in the example text.

    import sys
    from PyQt5 import QtCore, QtGui, QtWidgets
    class RgbPicker (QtWidgets.QLabel):
        # create a vertical color gradient similar to `Color Shower`,
        # used in QColorDialog
        colorGrads= QtGui.QLinearGradient (0, 0, 1, 0)
        colorGrads.setCoordinateMode (colorGrads.ObjectBoundingMode)
        xRatio= 1. /6
        colorGrads.setColorAt (0, QtCore.Qt.red)
        colorGrads.setColorAt (1, QtCore.Qt.red)
        colorGrads.setColorAt (xRatio, QtCore.Qt.magenta)
        colorGrads.setColorAt (xRatio * 2, QtCore.Qt.blue)
        colorGrads.setColorAt (xRatio * 3, QtCore.Qt.cyan)
        colorGrads.setColorAt (xRatio * 4, QtCore.Qt.green)
        colorGrads.setColorAt (xRatio * 5, QtCore.Qt.yellow)
        # add a `mask` gradient to support gradients for lighter colors
        maskGrad= QtGui.QLinearGradient (0, 0, 0, 1)
        maskGrad.setCoordinateMode (maskGrad.ObjectBoundingMode)
        maskGrad.setColorAt (0, QtCore.Qt.transparent)
        maskGrad.setColorAt (1, QtCore.Qt.white)
        # create a cross cursor to show the selected color
        cursorPath= QtGui.QPainterPath ()
        cursorPath.moveTo (-10, 0)
        cursorPath.lineTo (-4, 0)
        cursorPath.moveTo (0, -10)
        cursorPath.lineTo (0, -4)
        cursorPath.moveTo (4, 0)
        cursorPath.lineTo (10, 0)
        cursorPath.moveTo (0, 4)
        cursorPath.lineTo (0, 10)
        cursorPen= QtGui.QPen (QtCore.Qt.black, 3)
        colorChanged= QtCore.pyqtSignal (QtGui.QColor)
        showCursor= False
        cursorPos= QtCore.QPoint ()
        def __init __ (self, parent= None):
            super () .__ init __ (parent)
            self.setMouseTracking (True)
            self.setFixedSize (220, 200)
            # create a bitmap and paint over it with gradients
            pixmap= QtGui.QPixmap (self.size ())
            qp= QtGui.QPainter (pixmap)
            qp.fillRect (pixmap.rect (), self.colorGrads)
            qp.fillRect (pixmap.rect (), self.maskGrad)
            qp.end ()
            self.setPixmap (pixmap)
            # QImage is required to get the color of a specific pixel
            self.image= pixmap.toImage ()
            self.currentColor= QtGui.QColor ()
        def setColor (self, color):
            self.currentColor= color
            # calculate the coordinates of the cursor according to the color values;
            # this is based on the Hue /Saturation /Value data of the color
            h, s, v, a= color.getHsv ()
            x= (360 -h) * (self.width () -1) /360.
            y= (255 -s) * (self.height () -1) /255.
            self.cursorPos= QtCore.QPoint (x, y)
            self.showCursor= True
            self.update ()
        def mousePressEvent (self, event):
            if event.button ()== QtCore.Qt.LeftButton:
                # set current color and emit colorChanged signal
                self.currentColor= QtGui.QColor (self.image.pixel (event.pos ()))
                self.cursorPos= event.pos ()
                self.showCursor= True
                self.update ()
        def mouseMoveEvent (self, event):
            if event.pos () in self.rect ():
                color= QtGui.QColor (self.image.pixel (event.pos ()))
                self.colorChanged.emit (color)
                if event.buttons ()== QtCore.Qt.LeftButton:
                    # if the left button is pressed, update the current color
                    self.currentColor= color
                    self.cursorPos= event.pos ()
                    self.update ()
        def leaveEvent (self, event):
            # emit previously selected color on exit
            self.colorChanged.emit (self.currentColor)
        def paintEvent (self, event):
            # paint the "color shower"
            QtWidgets.QLabel.paintEvent (self, event)
            if self.showCursor:
                # paint the color "cursor"
                qp= QtGui.QPainter (self)qp.setPen (self.cursorPen) qp.translate (self.cursorPos)
                qp.drawPath (self.cursorPath)
    class ColorPicker (QtWidgets.QDialog):
        colorChanged= QtCore.pyqtSignal (QtGui.QColor)
        def __init __ (self, parent= None):
            super () .__ init __ (parent)
            self.setGeometry (650, 100, 240, 250)
            layout= QtWidgets.QVBoxLayout ()
            self.setLayout (layout)
            self.rgbPicker= RgbPicker (self)
            layout.addWidget (self.rgbPicker)
            self.rgbPicker.colorChanged.connect (self.colorChanged)
            buttonBox= QtWidgets.QDialogButtonBox (QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel)
            layout.addWidget (buttonBox)
            buttonBox.accepted.connect (self.accept)
            buttonBox.rejected.connect (self.reject)
        def getColor (self, color= None):
            if isinstance (color, QtGui.QColor):
                self.rgbPicker.setColor (color)
            # return color only if dialog is accepted
            if self.exec_ ():
                return self.rgbPicker.currentColor
    class MainWindow (QtWidgets.QWidget):
        def __init __ (self):
            super () .__ init __ ()
            # get the current background color, we must ignore the picker selection
            self.color= self.palette (). color (QtGui.QPalette.Window)
            self.colorPicker= ColorPicker (self)
            self.colorPicker.colorChanged.connect (self.setcolorChanged)
            self.colorChooser= QtWidgets.QPushButton ("ColorChooser", self)
            self.colorChooser.clicked.connect (self.onColorPicker)
            self.colorChooser.move (10, 10)
        def setcolorChanged (self, color):
            # set the stylesheet to `only` for this class, not its descendants,
            # otherwise you set the background for the `and` button of the color picker
            self.setStyleSheet ("MainWindow {background-color:% s;}"% color.name ())
        def onColorPicker (self):
            color= self.colorPicker.getColor (self.color)
            # update the color only if the dialog is accepted:
            # if the user presses the `Esc` key, it will be ignored
            if color:
                print ('ok', color.getRgb ())
                self.color= color
            self.setcolorChanged (self.color)
    if __name__== '__main__':
        app= QtWidgets.QApplication (sys.argv)
        w= MainWindow ()
        w.setGeometry (350, 100, 243, 253)
        w.show ()
        sys.exit (app.exec_ ())
    

    It's amazing! I will disassemble the code and do the task for myself -to change the shape of all this to make it look more beautiful.

    imapw_2021-09-27 10:52:23