stylesheet magic: setfont + polish = wrong background
-
After this label becomes child of MyW once you add into layout
Hope magic is clear now.Hm, nothing is clear. label become child after this:
auto lbl = new QLabel{"AAAA", this};
you see I pass
this
as argument forQLabel::QLabel(const QString &text, QWidget *parent, Qt::WindowFlags = ...)
, why you think that adding to layout change parent or something?Also this is not explain why
setFont
change background, and whysetStyleSheet("border:none;"); setStyleSheet(styleSheet() + "background:#ffffff;color:#000000;");
and
setStyleSheet("border:none;background:#ffffff;color:#000000;");
gives different results -
I did not notice 'this' is passed while constructing. So parent will not change. If you put polished at the end, it will apply this. Can you look ensurePolished method(). It gives you the idea how it works. Last applied style are taking for label rather from parent. If you move up the polished, last applied styles are from parent.
-
Also from the doc:
If you subclass from QWidget, you need to provide a paintEvent for your custom QWidget as below: void CustomWidget::paintEvent(QPaintEvent *) { QStyleOption opt; opt.init(this); QPainter p(this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); } The above code is a no-operation if there is no stylesheet set. Warning: Make sure you define the Q_OBJECT macro for your custom widget.
-
Hi
Just as a note
void CustomWidget::paintEvent(QPaintEvent *)
{
QStyleOption opt;
opt.init(this);
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}- The above code is a no-operation if there is no stylesheet set.
Its not a no-operation. the QStyle::PE_Widget style is just very basic and have no background color or frame.
most other QStyle::PE_xxxx are a bit more interesting :)Regarding your issue.
You are not using any selectors in the your style sheets and since
sheets are cascading ( affects children too) ,
it often result in a mess assigning style sheet through the whole program.so what color do the label get ?
I would guess on #f0f4f7 ? -
You are not using any selectors in the your style
Yep, this is intented, I have only two background colors in whole program,
and I want that all widgets have them. And I expecthttp://doc.qt.io/qt-5/stylesheet-syntax.html#cascading
When conflicts arise, the widget's own style sheet is always preferred to any inherited style sheet, irrespective of the specificity of the conflicting rules. Likewise, the parent widget's style sheet is preferred to the grandparent's, etc.
And sometimes and I get this behaviour for example if I remove
lbl->ensurePolish()
so what color do the label get ?
I would guess on #f0f4f7 ?Yes
#f0f4f7
while I expect#ffffff
and can get it by three ways:- Do not call lbl->ensurePolish() in
MyW::MyW
- Set full style with one call of
setStyleSheet
instead of two inMyW::MyW
- Remove code that setFont in
MyW::MyW
- Do not call lbl->ensurePolish() in
-
@DaveMilter
Ok, Do note that QApplication also have setStyleSheet allowing to affect all widgets in app.
Could you try
ui->label->parent()->objectName();
and see whom its daddy ? ( after inserted into layout) -
Ok, Do note that QApplication also have setStyleSheet allowing to affect all widgets in app.
Could you try
ui->label->parent()->objectName();
and see whom its daddy ? ( after inserted into layout)Why you all are so suspicious about layout,
I remove in code bellow all stuff related to layout.
And print "family tree" ofQLabel
:font pixel size 30 qapp style: "" Page: QWidget(0x7ffee3a13190) MyW: QWidget(0x559fb05749d0) lbl family tree lbl parent 0 th gen QLabel(0x7effb0005560) lbl parent 1 th gen QWidget(0x559fb05749d0) lbl parent 2 th gen QWidget(0x7ffee3a13190)
#include <QApplication> #include <QLabel> #include <QtDebug> class MyW : public QWidget { public: MyW(QWidget *parent) : QWidget(parent) { qDebug() << "MyW: " << static_cast<QObject *>(this); setStyleSheet("border:none;"); auto font = QApplication::font(); if (font.pixelSize() != -1) { font.setPixelSize(static_cast<int>(font.pixelSize() * 1.25 + 0.5)); setFont(font); } setStyleSheet(styleSheet() + "background:#ffffff;color:#000000;"); auto lbl = new QLabel{"AAAA", this}; { qDebug("lbl family tree"); QObject *o = lbl; int i = 0; while (o != nullptr) { qDebug() << "lbl parent " << i << "th gen " << o; ++i; o = o->parent(); } } lbl->ensurePolished(); } }; class Page : public QWidget { public: Page(QWidget *parent) : QWidget{parent} { qDebug() << "Page: " << static_cast<QObject *>(this); setStyleSheet("background:#f0f4f7;"); auto item = new MyW{this}; } }; int main(int argc, char *argv[]) { QApplication a(argc, argv); QFont font("Arial"); font.setFixedPitch(false); font.setBold(true); font.setPixelSize(30); qInfo() << "font pixel size " << font.pixelSize(); QApplication::setFont(font); qDebug() << "qapp style: " << a.styleSheet(); Page p{nullptr}; p.resize(400, 800); p.show(); return a.exec(); } ```
-
Hi
I think the multiple setting of stylesheet in ctor confuses it.
if you ensurePolished() for myW it seems to work as expected.
(using Parent style sheet)class MyW : public QWidget { public: MyW(QWidget *parent) : QWidget(parent) { qDebug() << "MyW: " << static_cast<QObject *>(this); setStyleSheet("border:none;"); ensurePolished(); // <<<<<<<<<<<<<<<<<<<<<<<<< auto font = QApplication::font(); if (font.pixelSize() != -1) { font.setPixelSize(static_cast<int>(font.pixelSize() * 1.25 + 0.5)); setFont(font); } setStyleSheet(styleSheet() + "background:#ffffff;color:#000000;"); auto lbl = new QLabel{"AAAA", this}; lbl->ensurePolished(); // not needed } };
-
I think the multiple setting of stylesheet in ctor confuses it.
if you ensurePolished() for myW it seems to work as expected.yeah, but this is not explain why if I remove
setFont
fromMyW::MyW
multiple setting of stylesheet works completly fine,
without extra call ofMyW::ensurePolished
,also if I change
MyW::MyW
to this all works fine (white background),
sosetFont
somehow become interferenceMyW(QWidget *parent) : QWidget(parent) { qDebug() << "MyW: " << static_cast<QObject *>(this); setStyleSheet("border:none;"); setStyleSheet(styleSheet() + "background:#ffffff;color:#000000;"); auto font = QApplication::font(); if (font.pixelSize() != -1) { font.setPixelSize(static_cast<int>(font.pixelSize() * 1.25 + 0.5)); setFont(font); } auto lbl = new QLabel{"AAAA", this}; lbl->ensurePolished(); }
-
I solved this question with SO help: https://stackoverflow.com/questions/53675808/mix-setstylesheet-and-setfont-wrong-background