QT开发中,经常会使用自定义属性来更新控件的样式,例如一个QLabel,如果显示文字的颜色需要变化,当一会显示红色,一会显示白色,有一种常见的做法是给这个label设置一个属性,例如 “select”,根据属性值的不同,使用不同的样式:
QLabel[select="true"]
{
background:transparent;
color:red;
}
QLabel
{
background:transparent;
color:green
}
//---------------------------------------------------------------------
//do some thing
ui->label->setProperty("select", true);
//do some thing
ui->label->setProperty("select", false);
仅仅这样写,是不能让样式生效的,还必须要调用:
ui->label->style()->unpolish(label)
ui->label->style()->polish(label)
这是因为:
Qt在第一次设置QWidget的样式时,会进行"polish"操作,这个操作会把样式信息缓存起来。之后如果只是设置属性;比如设置select属性的值,并不会重新触发样式的计算,导致QLabel无法感知select属性的变化,还是使用之前缓存的样式。
调用unpolish可以清除之前的样式缓存。
再调用polish就会重新计算QWidget的样式,此时会根据当前select属性值选择合适的qss规则进行渲染。
内置属性
上面的例子中,给QLabel自定义了一个"select"属性,修改属性的值,并调用 unpolish() 与 polish()主动通知Qt来刷新控件的样式;这是因为 "select"是我们自定义的样式,如果使用的是控件的内置属性(例如:text、checked等)来刷新样式,是不需要我们主动调用unpolish() 与 polish()的,Qt系统本身可以自动感知内置属性的变化。
例如以下这种写法就无需主动调用 unpolish()和polish()
QPushButton:checked
{
color:green
}
QPushButton:!checked
{
color:red;
}
//---------------------------------------------------------------------
//do some thing
ui->pushButton->setChecked(true);
//do some thing
ui->pushButton->setChecked(false);
性能
从性能角度来看,使用控件的内置属性来更新样式比使用自定义属性更新样式更快,原因如下:
- 对于内置属性,Qt框架本身就内置了属性变化监测机制,可以自动检测属性值的变化并触发样式更新。
- 而对于自定义属性,需要开发者主动调用style().unpolish()和style().polish()来通知Qt属性变化,从而触发样式更新。这涉及到额外的函数调用开销。
- 内置属性变化Qt可以直接使用内部机制监测和更新样式,而自定义属性需要开发者主动参与,过程更复杂一些。
- 此外,内置属性Qt框架内部可能针对常见控件做了一定的优化,性能可能比自定义属性处理更高效。
- 例如直接修改text属性,Qt可能直接使用字符串拷贝来更新文本,而不是完全重绘控件。
所以总体来说:
- 使用内置属性样式更新,Qt框架可以直接高效处理,无额外开销。
- 使用自定义属性需要额外的unpolish和polish调用,增加了一定开销。
- 所以从速度上看,内置属性样式更新速度会更快。
但使用自定义属性也有其必要之处,主要看具体需求和场景选择合适的方法。总体来说,内置属性方式性能会更优一些。