CSS class selector not working with container widgets
-
Using QT5.15.2 msvc 32-bit.
I have a window which contains the following structure:
QMainWindow ---> QWidget -------> QTabWidget -----------> QComboBox
Where the
QWidget
has a class property (class="className").
Styling the QCombox only works correctly if it is created dynamically.Using the following css, the drop-down menu of the
QComboBox
only shows yellow if it is created dynamically..className QComboBox QAbstractItemView { background-color: yellow; }
Code to create
QComboBox dynamically
:QComboBox* box = new QComboBox(); box->addItem("a"); box->addItem("b"); this->ui->tabWidget->currentWidget()->layout()->addWidget(bx2);
But any
QComboBox
that is inside theQWidget
but not in theQTabWidget
is styled correctly. Or if I remove the.className
selector from the css.So it seems like a problem with
QTabWidget
, and having.className
andQAbstractItemView
on the same css statement. -
After some testing it seems that because in the ui file the class properties are set after all the widgets are created and added, the
QComboBoxListView
private class's style does not get updated.But if the class properties are added straight after the widget is created, the it is styled correctly.
Ui file from:
void setupUi(...) { widget = new QWidget(...); comboBox = new QComboBox(widget); ... retranslateUi(MainWindow); // sets class properties }
To
void setupUi(...) { widget = new QWidget(...); widget.setProperty("class", "test"); // coptied from restranslateUi function comboBox = new QComboBox(widget); ... retranslateUi(MainWindow); // sets class properties }
Obviously this is not a usable solution because the ui_*.h file is auto generated.
Another way to fix this is to re-polish the
QComboBoxListView
by recursively re-polishingQComboBox
and it's childrenvoid recursively_polish(QObject* object) { auto* widget = dynamic_cast<QWidget*>(object); if (widget!=nullptr){ widget->style()->unpolish(widget); widget->style()->polish(widget); } auto children = object->findChildren<QObject*>(QString(), Qt::FindDirectChildrenOnly); for (auto& child : children){ polish_recursive(child); } }
Is this the only way to fix it, or is there another better way?
-
@ashbob999
I had been going to ask what you had done about polishing, given your behaviour, but you have answered. So far as I know this is indeed required/best/simplest, see discussion Is there a better method than calling polish recursively on all children of a QWidget?