我将几个类和函数合并为两个类,
所以它看起来很奇怪和丑陋。
我的类 MyW
在构造函数末尾的问题
将背景设置为白色,但它的子 QLabel 有背景
来自 Page
,而不是来自 MyW
。
问为什么?
我知道如果我用 MyW
中的字体移除魔法,
或者像这样在开头调用 setStyleSheet:
setStyleSheet("border:none;background:#ffffff;color:#000000;");
我得到正确的结果(白色背景),
但我不明白为什么字体会对背景产生影响,
以及为什么分两步设置样式表之间存在差异,
而不是一个?
#include <QApplication>
#include <QLabel>
class MyW : public QWidget {
public:
MyW(QWidget *parent) : QWidget(parent) {
setStyleSheet("border:none;");
setFont(QFont{"Arial", 42});
setStyleSheet(styleSheet() + "background:#ffffff;color:#000000;");
auto lbl = new QLabel{"AAAA", this};
lbl->ensurePolished();
}
};
class Page : public QWidget {
public:
Page(QWidget *parent) : QWidget{parent} {
setStyleSheet("background:#f0f4f7;");
auto item = new MyW{this};
}
};
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
Page p{nullptr};
p.resize(400, 800);
p.show();
return a.exec();
}
更新:我删除了所有不重要的部分,比如布局、QApplication::setFont 等等。
最佳答案
我确信原因不在 auto font = QApplication::font();
中,但是
在 QWidget::setFont
调用中。您可以检查它,例如,通过将字体内容替换为:
QFont font;
font.setPixelSize(42);
setFont(font);
这背后的“魔法”是 Qt 内部用来处理样式表的缓存。
您可以在 qtbase/src/widgets/styles/qstylesheetstyle.cpp 中找到提示,看看用法
静态 QStyleSheetStyleCaches *styleSheetCaches = 0;
Qt 不直接使用 QWidget::styleSheet
属性,
它解析它并缓存结果。
QWidget::styleSheet
的解析(重新解析)有几个触发器:
QWidget::ensurePolished
调用(当您的小部件自动完成时 第一次可见);- 调用
setStyleSheet
,但前提是您的小部件至少调用了一次QWidget::ensurePolished
; - 调用
QWidget::setFont
或QWidget::setPalette
(仅当您的小部件没有空样式表时)。
在您的情况下,您的问题是 (1-2) 和 (3) 的组合:
通过 QWidget::setFont
强制缓存已解析的样式表后,您的小部件仍未“抛光”,
所以下一次调用 setStyleSheet
不会更新在 setFont
步骤中创建的缓存样式表,
所以在使用 lbl->ensurePolished();
的步骤中,您实际上有一个带有“border:none;”的样式表加上字体,加上 parent 的背景。
您可以在 lbl->ensurePoslished()
之前调用 this->ensurePoslished()
来解决这个问题,或者按照@William Miller 的建议使用样式表设置字体,
或在 setStyleSheet
setFont
关于c++ - 混合 setStyleSheet 和 setFont : wrong background,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53675808/