如何解决Qt读取样式表中的动态qproperties
我正在编写一个包含具有不同Qt属性的窗口小部件的应用程序。这些属性之一是简单的颜色属性:
Q_PROPERTY(QColor color GET color SET setColor NOTIFY colorChanged)
我希望能够从样式表中访问此属性以更改小部件的外观。 样式表将由用户提供,并且不能在应用程序中动态创建。 我不知道用户想要使应用程序看起来像什么,但是我想给他们机会根据小部件的动态属性设置颜色(和其他属性):
MyWidget {
border: 1px solid red;
background-color: <color property value>
}
在颜色方面,根据Qt documentation,应通过访问小部件的调色板来实现所需的行为:
MyWidget {
border: 1px solid red;
background-color: palette(window);
}
但是,正如许多人已经报告过的那样,这似乎并没有达到预期的效果,因为样式表不会访问小部件自己的调色板,而是访问应用程序调色板。
如Qt wiki中所述,可以使用选择器读取或使用qproperty-
作为写入前缀来访问动态属性。
MyWidget {
border: 1px solid red;
qproperty-color: red;
}
MyWidget[color="red"] {
border: 1px solid red;
}
(注意:我不确定这个选择器是否可以正常工作,我还没有尝试过使用颜色)。 现在,如果我有少量可能的颜色,这将适合我的情况。 但是,我的应用程序动态计算颜色,这将导致2 ^ 24(不计算alpha)颜色。
看到可以通过使用qproperty-color: <value>;
获得对属性的写访问权,我希望读访问权在语法上是对称的:
MyWidget {
border: 1px solid red;
background-color: qproperty-color;
}
但是,这不起作用,因此我在这里发布。
是否有人找到其他方法来访问属性,并在样式表中使用它们来更改小部件的外观,而无需事先知道可能的值?
解决方法
一个月前,我遇到了类似的问题,并且我也尝试使用StyleSheet
解决此问题,但最终放弃了将StyleSheet
用于QPalette
的想法。
使用StyleSheet更改小部件的外观需要进行很多工作,尤其是当小部件的大小可调整时。我建议改用QPalette
。但是,使用QPalette
有一个陷阱:有些样式,尤其是像window
这样的默认样式,不能让您覆盖该样式调色板的所有属性。我建议将应用程序的默认样式更改为fusion
并在应用程序中使用其调色板:
#include "mainWindow.h"
#include <QtWidgets/QApplication>
#include <QStyleFactory>
#include "start.h"
int main(int argc,char *argv[])
{
QApplication::setStyle(QStyleFactory::create("Fusion")); // Setting Fusion Style
QPalette light = QApplication::palette(); // Getting Fusion Style Palette
Start S(light); // Making Changes to the palette
QApplication A(argc,argv);
mainWindow W(&S,&A); // Passing the palette to main window so that you can change it dynamically
W.show();
return A.exec();
}
使用fusion
样式有很多优点:
- 支持定制几乎所有
ColorGroup
和ColorRole
- 有一个黑暗的主题:FusionDarkTheme
- 比
StyleSheet
更容易维护
要更改小部件的背景,您还必须将其autoFillBackground
值设置为true
,否则其父级的背景将覆盖小部件的背景。这是您无法更改窗口小部件的背景颜色的原因之一。您不必为每个小部件分别进行更改,您可以像这样:
void mainWindow::setAutoBackgroundForWidget()
{
QList<QWidget *> widgets = this->findChildren<QWidget *>();
for(QWidget *wid : qAsConst(widgets))
{
QList<QByteArray> pro = wid->dynamicPropertyNames();
if(!pro.isEmpty())
{
for(QByteArray byt : qAsConst(pro))
{
if(byt == "Level")
{
wid->setAutoFillBackground(true);
}
}
}
}
}
上面的函数setAutoBackgroundForWidget()
是我创建的函数,我在mainWindow
的构造函数结束之前调用了该函数。此函数选择所有具有动态属性“ Level”的小部件,使其具有自己的背景,而不使用其父级的背景。您可以相应地修改上述功能,以选择所需的小部件。
完成上述操作后,剩下的就是使用QColorDialog
向用户询问他们需要的颜色,复制当前调色板并将其中的给定ColorRole
更改为新的调色板。使用setPalette()
为新的调色板上色并将其应用于您的小部件。您还可以在mainWindow
cpp文件中的单个函数中为所有小部件完成该操作。
对于StyleSheet
,我可以确认以下工作:
MyWidget[color="red"] {
border: 1px solid red;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。