I have to edit the stylesheet of the QColorDialog widget internal components

1.1k Views Asked by At

I am able to set style sheet of QColorDialog children like spin box, labels and push button by the style sheet code given below

QColorDialog QPushButton 
{
border : 2px solid black;
background : green;
}

But I am not able to set stylesheet of each internal components, I have searched in the documentation but no description is given for styling color dialog, although for widgets like QCalendarWidget we used QCalendarWidget QWidget#qt_calendar_navigationbar to style the tool bar of the calendar, i think each component should have particular name

1

There are 1 best solutions below

0
On BEST ANSWER

While some complex widgets have child widgets with an object name property set (like in the QCalendarWidget), an object name is not mandatory for all Qt objects; I believe that the developers set those names only for specific child widgets whenever that is required for some reason.

Looking at the source code of QColorDialog, no widget have an object name set, so you can only access them using findChild or findChildren and set stylesheets individually or manually set their object name.

Note that QColorDialog is created "privately", there's no direct access to its widgets and its structure might differ in different versions of Qt.
Also consider that the following widgets in that dialog are private and are not standard widgets (so you cannot access them in any way):

  • the standard color table
  • the custom color list
  • the color picker
  • the color preview

The only "constant" would probably be the spinboxes, the html color QLineEdit, and the dialog button box (assuming you've not set the NoButtons option, obviously).

Assuming that the spinboxes are always created in the same order (but, remember, you cannot give this for granted!), you can navigate through the layout, set the object names for them and then style the whole dialog using the # selector, which can be used to style a specific widget based on its object name. You could also use dialog.findChildren(QtWidgets.QSpinBox) instead.

In the following code, I'm making the Ok button green and the Cancel button red, and I also set the background of each spinbox and the HTML color line edit:

from PyQt5 import QtWidgets
import sys

app = QtWidgets.QApplication(sys.argv)
dialog = QtWidgets.QColorDialog()
dialog.setOption(dialog.ShowAlphaChannel)

grid = dialog.findChild(QtWidgets.QGridLayout)
names = iter(('hue', 'sat', 'val', 'red', 'green', 'blue', 'alpha'))
for i in range(grid.count()):
    item = grid.itemAt(i)
    widget = item.widget()
    if isinstance(widget, QtWidgets.QSpinBox):
        widget.setObjectName(next(names))

# alternatively:
#spins = dialog.findChildren(QtWidgets.QSpinBox)
#names = 'hue', 'sat', 'val', 'red', 'green', 'blue', 'alpha'
#for name, spin in zip(names, spins):
#    spin.setObjectName(name)

buttonBox = dialog.findChild(QtWidgets.QDialogButtonBox)
buttonBox.button(buttonBox.Ok).setObjectName('ok')
buttonBox.button(buttonBox.Cancel).setObjectName('cancel')

dialog.setStyleSheet('''
    /* the HTML color line edit */
    QLineEdit {
        background: yellow;
    }

    /* the spin boxes */
    QSpinBox#hue {
        background: coral;
    }
    QSpinBox#sat {
        background: orange;
    }
    QSpinBox#val {
        background: lightgray;
    }
    QSpinBox#red {
        background: orangered;
    }
    QSpinBox#green {
        background: lime;
    }
    QSpinBox#blue {
        background: aqua;
    }
    QSpinBox#alpha {
        background: pink;
    }

    /* buttons that are children of QDialogButtonBox */
    QDialogButtonBox QAbstractButton#ok {
        background: green;
    }
    QDialogButtonBox QAbstractButton#cancel {
        background: red;
    }
    ''')

dialog.show()
sys.exit(app.exec_())

screenshot of the stylesheet applied to the dialog