Search code examples
pythonpyqtpyqt4qmenu

How to display color icons in menu, PyQt?


What i'm trying to achieve is to display color icons in a context menu, in python. So that it displays some of the used colors to mark the table.

Here is an example of what i'm trying to achieve.

enter image description here

Any guess how to do this ?

UPDATE Here is a more detailed version of my vision.

On clicking Mark , a sub menu opens up with color options.

enter image description here


Solution

  • You can do this fairly easily using a QWidgetAction.

    The example code below uses tool-buttons with icons for the grid of colors, but there are many other widgets could just as easily be be used. The palette method can be reimplemented if you need a different set of colors.

    class ColorAction(QtGui.QWidgetAction):
        colorSelected = QtCore.pyqtSignal(QtGui.QColor)
    
        def __init__(self, parent):
            QtGui.QWidgetAction.__init__(self, parent)
            widget = QtGui.QWidget(parent)
            layout = QtGui.QGridLayout(widget)
            layout.setSpacing(0)
            layout.setContentsMargins(2, 2, 2, 2)
            palette = self.palette()
            count = len(palette)
            rows = count // round(count ** .5)
            for row in range(rows):
                for column in range(count // rows):
                    color = palette.pop()
                    button = QtGui.QToolButton(widget)
                    button.setAutoRaise(True)
                    button.clicked[()].connect(
                        lambda color=color: self.handleButton(color))
                    pixmap = QtGui.QPixmap(16, 16)
                    pixmap.fill(color)
                    button.setIcon(QtGui.QIcon(pixmap))
                    layout.addWidget(button, row, column)
            self.setDefaultWidget(widget)
    
        def handleButton(self, color):
            self.parent().hide()
            self.colorSelected.emit(color)
    
        def palette(self):
            palette = []
            for g in range(4):
                for r in range(4):
                    for b in range(3):
                        palette.append(QtGui.QColor(
                            r * 255 // 3, g * 255 // 3, b * 255 // 2))
            return palette
    
    class ColorMenu(QtGui.QMenu):
        def __init__(self, parent):
            QtGui.QMenu.__init__(self, parent)
            self.colorAction = ColorAction(self)
            self.colorAction.colorSelected.connect(self.handleColorSelected)
            self.addAction(self.colorAction)
            self.addSeparator()
            self.addAction('Custom Color...')
    
        def handleColorSelected(self, color):
            print(color.name())