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 -----------> QComboBoxWhere the
QWidgethas 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
QComboBoxonly 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
QComboBoxthat is inside theQWidgetbut not in theQTabWidgetis styled correctly. Or if I remove the.classNameselector from the css.So it seems like a problem with
QTabWidget, and having.classNameandQAbstractItemViewon 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
QComboBoxListViewprivate 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
QComboBoxListViewby recursively re-polishingQComboBoxand 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?
-
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
QComboBoxListViewprivate 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
QComboBoxListViewby recursively re-polishingQComboBoxand 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? -
@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?