Houdini 20.5 Python scripting hou hou.qt

hou.qt.ColorPalette class

A convenient widget for quick olor selection from a small palette of colors.

On this page

Overview

Sometimes, you want to allow users to choose a color from a list of predefined colors, without burdening them with the requirement to specify their own custom color each time. For example, when “tagging” items in a user interface with different colors to keep them organized.

This widget lets you specify a list of colors, and have the user select from that list, with the optional ability to edit the colors.

This object works two ways:

  • You can use it as a pop-up window, where a palette window pops open, the user clicks a color, and the palette window disappears.

  • Or, you can embed it as a regular Qt widget in a widget layout. This would be useful, for example, in a preferences window, where you want to provide a palette from which to pick a color for something.

Using ColorPalette as a popup

The color palette is non-modal. Once you open it, your script continues to run, and you have to use signals to get feedback on how the user interacts with the palette.

class MyWindow(QtWidgets.QDialog):
    def __init__(self, parent=None):
        super(MyWindow, self).__init__(parent)

        self._colors = [
            QtGui.QColor(255, 0, 0),
            QtGui.QColor(0, 255, 0),
            QtGui.QColor(0, 0, 255),
            QtGui.QColor(255, 255, 0),
            QtGui.QColor(255, 0, 255),
            QtGui.QColor(0, 255, 255),
            QtGui.QColor(255, 128, 0),
            QtGui.QColor(255, 255, 255),
            QtGui.QColor(0, 0, 0),
        ]

        self._palette = ColorPalette(self._colors)
        self._palette.colorSelected.connect(self._chose_color)

        layout = QtWidgets.QVBoxLayout()
        self.setLayout(layout)

        self._label = QtWidgets.QLabel("No color")
        layout.addWidget(self._label)
        self._button = QtWidgets.QPushButton("Choose")
        self._button.clicked.connect(self._palette.show)
        layout.addWidget(self._button)

    def _chose_color(self, ix, color):
        msg = "Color #{}, R: {}, G: {}, B: {}".format(
            ix, color.red(), color.green(), color.blue()
        )
        self._label.setText(msg)

Note

Remember that you must have at least one persistent reference to the widget, otherwise the window will be garbage collected and immediately close.

Embedding ColorPalette as a widget in a Qt layout

You can simply use ListEditor as a widget, and use signals to react when users interact with the palette.

class MyWindow(QtWidgets.QDialog):
    def __init__(self, parent=None):
        super(MyWindow, self).__init__(parent)

        self._colors = [
            QtGui.QColor(255, 0, 0),
            QtGui.QColor(0, 255, 0),
            QtGui.QColor(0, 0, 255),
            QtGui.QColor(255, 255, 0),
            QtGui.QColor(255, 0, 255),
            QtGui.QColor(0, 255, 255),
            QtGui.QColor(255, 128, 0),
            QtGui.QColor(255, 255, 255),
            QtGui.QColor(0, 0, 0),
        ]

        layout = QtWidgets.QVBoxLayout()
        self.setLayout(layout)

        self._label = QtWidgets.QLabel("No color")
        layout.addWidget(self._label)

        self._palette = ColorPalette(self._colors, size=24)
        self._palette.colorSelected.connect(self._chose_color)
        self._palette.colorEdited.connect(self._edited_color)
        layout.addWidget(self._palette)

    def _chose_color(self, ix, color):
        msg = "Color #{}, R: {}, G: {}, B: {}".format(
            ix, color.red(), color.green(), color.blue()
        )
        self._label.setText(msg)

Swatch layout

  • The size of the widget is derived from the swatch size (the size argument to the initializer) and the number of colors in the palette.

  • By default, the palette will try to lay out the swatches in as close to a square as possible.

  • If there aren’t enough colors to fill the layout, swatches can be empty.

  • If you specify a columns argument to the initializer, the widget will only allow that number of columns, with swatches going down to create more rows.

  • If you specify a rows argument to the initializer, the widget will only allow that number of rows, with swatches going across to create more columns.

  • If you specify both rows and columns, the layout will have exactly that number of rows and columns, even if this means you can’t see all the colors in the color list.

  • By default colors in the list are ordered by filling up the first row left to right, then second row, and so on. If you pass by_column=True to the initializer, the widget will instead order the colors by filling in the first column top to bottom, then the second column, and so on.

Allowing the user to edit colors

By default, the user can Alt-click a color in the palette to edit that swatch’s color value. When the user accepts the edited color (that is, doesn’t cancel the edit operation), the widget emits a colorEdited signal.

Note that the edited palette is kept in the ColorPalette object. If you want to persist the palette between uses of different ColorPalette objects, or across sessions, you will need to do that yourself.

To prevent the user from editing colors, pass allow_editing=False when you create the widget, or call setEditingAllowed(False) on the widget.

Background colors

  • By default, the background of the widget is filled with the default window background from the current palette. You can pass a bg_color to the initializer to specify a custom color (or brush).

  • Empty swatches are painted with a special brush. The default brush draws dark or light diagonal lines. You can pass an empty_color to the initializer to specify a custom color (or brush) for empty squares.

Tips and notes

  • The “colors” in the list may be QBrush objects, not just QColor objects. You could use QBrush objects to set gradients, patterns, and textures as swatches in the palette instead of or alongside plain colors.

Signals

paletteChanged()

Triggered when the entire palette is replaced by setColorList().

colorEdited(index: int, old: QColor, new: QColor)

Triggered when the user manually edits one of the colors (see color editing above).

colorSelected(index: int, color: QColor)

Triggered when the user selects a color in the palette. The signal can be triggered multiple times by the user dragging over different colors, or if you have embedded the widget in a layout so users can change the color selection as many times as they want. If you only want to react when the user chooses a color from a popup and the popup closes, use the colorAccepted signal instead.

colorAccepted(index: int, color: QColor)

Only triggered when the user releases the mouse button on a color in a popup and the popup closes.

colorCancelled()

Triggered if the user closes the popup without choosing a valid color, for example by clicking outside the popup, or clicking an empty space.

Methods

hou.qt