Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. stylesheet magic: setfont + polish = wrong background
Forum Updated to NodeBB v4.3 + New Features

stylesheet magic: setfont + polish = wrong background

Scheduled Pinned Locked Moved Solved General and Desktop
solved
13 Posts 4 Posters 2.5k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    dheerendra
    Qt Champions 2022
    wrote on 8 Dec 2018, 05:58 last edited by
    #4

    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.

    Dheerendra
    @Community Service
    Certified Qt Specialist
    http://www.pthinks.com

    1 Reply Last reply
    0
    • N Offline
      N Offline
      NicolasS
      wrote on 8 Dec 2018, 08:09 last edited by
      #5

      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.
      

      Source: http://doc.qt.io/qt-5/stylesheet.html

      D 1 Reply Last reply 8 Dec 2018, 09:43
      0
      • N NicolasS
        8 Dec 2018, 08:09

        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.
        

        Source: http://doc.qt.io/qt-5/stylesheet.html

        D Offline
        D Offline
        DaveMilter
        wrote on 8 Dec 2018, 09:43 last edited by
        #6

        @NicolasS

        If you subclass from QWidget

        The problem completly reproducible with Q_OBJECT and paintEvent override for MyW and Page, so I remove this code to make example smaller and fit it to one c++ file.

        1 Reply Last reply
        0
        • M Offline
          M Offline
          mrjj
          Lifetime Qt Champion
          wrote on 8 Dec 2018, 10:30 last edited by
          #7

          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 ?

          D 1 Reply Last reply 8 Dec 2018, 10:42
          2
          • M mrjj
            8 Dec 2018, 10:30

            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 ?

            D Offline
            D Offline
            DaveMilter
            wrote on 8 Dec 2018, 10:42 last edited by DaveMilter 12 Aug 2018, 10:44
            #8

            @mrjj

            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 expect

            http://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 in MyW::MyW
            • Remove code that setFont in MyW::MyW
            M 1 Reply Last reply 8 Dec 2018, 10:50
            0
            • D DaveMilter
              8 Dec 2018, 10:42

              @mrjj

              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 expect

              http://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 in MyW::MyW
              • Remove code that setFont in MyW::MyW
              M Offline
              M Offline
              mrjj
              Lifetime Qt Champion
              wrote on 8 Dec 2018, 10:50 last edited by
              #9

              @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)

              D 1 Reply Last reply 8 Dec 2018, 11:05
              1
              • M mrjj
                8 Dec 2018, 10:50

                @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)

                D Offline
                D Offline
                DaveMilter
                wrote on 8 Dec 2018, 11:05 last edited by
                #10

                @mrjj

                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" of QLabel:

                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();
                }
                ```
                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  mrjj
                  Lifetime Qt Champion
                  wrote on 8 Dec 2018, 11:41 last edited by mrjj 12 Aug 2018, 11:42
                  #11

                  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
                      }
                  };
                  
                  
                  D 1 Reply Last reply 8 Dec 2018, 12:42
                  0
                  • M mrjj
                    8 Dec 2018, 11:41

                    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
                        }
                    };
                    
                    
                    D Offline
                    D Offline
                    DaveMilter
                    wrote on 8 Dec 2018, 12:42 last edited by
                    #12

                    @mrjj

                    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 from MyW::MyW
                    multiple setting of stylesheet works completly fine,
                    without extra call of MyW::ensurePolished,

                    also if I change MyW::MyW to this all works fine (white background),
                    so setFont somehow become interference

                      MyW(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();
                    }
                    
                    1 Reply Last reply
                    0
                    • D Offline
                      D Offline
                      DaveMilter
                      wrote on 26 Jan 2019, 12:57 last edited by
                      #13

                      I solved this question with SO help: https://stackoverflow.com/questions/53675808/mix-setstylesheet-and-setfont-wrong-background

                      1 Reply Last reply
                      2

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved