spraff
spraff

Reputation: 33445

Why does my QWidget stylesheet not recognise objectName rules?

Here I have a subclass of QComboBox which is going to change the colour of its text according to the validity of its contents.

namespace
{
    const QString GOOD = "good";
    const QString BAD  = "bad";
}

NewDBLabel :: NewDBLabel( DB db, const QString & table ) :
    m_db (db)
{
    connect (this, SIGNAL (textChanged (const QString &)),
            this,  SLOT   (changed     (const QString &)));

    setStyleSheet (
        "QWidget#" + GOOD + " {color: black;} "
        "QWidget#" + BAD  + " {color: darkRed;}");
}
    
void NewDBLabel :: changed (const QString & label)
{
    if (m_db .label_exists (m_table, label))
    {
        qWarning ("exists"); // this is printed correctly
        setObjectName (BAD);
        emit valid (false);
    }
    else
    {
        qWarning ("new"); // this is printed correctly
        setObjectName (GOOD);
        emit valid (true);
    }
}

As far as I can tell, this conforms to the documentation: QWidget#foo should match subclasses of QWidget whose objectName is foo.

I expected that setObjectName would cause the different style rules to be applied, but this doesn't happen. Any idea why?

Upvotes: 3

Views: 1901

Answers (1)

Jablonski
Jablonski

Reputation: 18514

Syntax is correct, but stylesheet is not so dynamic. In your code you setObjectName() after setting stylesheet, so objectName was changed, but qss was not re-applied. So try to unpolish/polish widget. In this case qss will be able to detect new objectNames and properties.

For example:

//in ctor
ui->pushButton->setStyleSheet("QWidget#good {color: green;}"
                              "QWidget#bad  {color: red;}  ");
//in handler
if(ui->pushButton->objectName() == "good")
    ui->pushButton->setObjectName("bad");
else
    ui->pushButton->setObjectName("good");

ui->pushButton->style()->unpolish(ui->pushButton);
ui->pushButton->style()->polish(ui->pushButton);

However, re-applying a stylesheet should be avoided, because the best and fastest way is to unpolish/polish the widget. Moreover, setStyleSheet() calls polish() and also parses the whole string again, so it is just completely unnecessary step, which only reduces performance.

Upvotes: 5

Related Questions