Reputation: 33445
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
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