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. QSpinBox cannot set its QLineEdit background colour under Linux
QtWS25 Last Chance

QSpinBox cannot set its QLineEdit background colour under Linux

Scheduled Pinned Locked Moved Unsolved General and Desktop
15 Posts 3 Posters 2.3k Views
  • 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.
  • JonBJ Offline
    JonBJ Offline
    JonB
    wrote on last edited by JonB
    #1

    I am Ubuntu 19.04 with the Qt 5.12.2 which was released with it. [EDIT: It now appears this has nothing to do with Linux or Qt version, nor even just background colour, see my later post + sample code. ] You cannot set the background colour of the QLineEdit in a QSpinBox:

    QSpinBox spin = new QSpinBox(whatever);
    QLineEdit lineEdit = spin->findChild<QLineEdit*>();
    Q_ASSERT(lineEdit);
    lineEdit->setStyleSheet("background-color: blue;");
    

    has no effect. Note the following:

    • I have tried QPalette::setColor(QPalette::Base, ...) (plus QLineEdit::setAutoFillBackground(true)) instead of stylesheet, same no effect.

    • You can set anything else stylesheet/palette, like the text colour, on the line edit, it's only the background color does not work.

    • Either method does work on a standalone QLineEdit, just not in the QSpinBox one, which only seems to have plain QLineEdit attached.

    • Background color does work if I set it on the QSpinBox itself (and inherits down to the line edit) rather than on the QLineEdit only, but that's not what i want.

    Most importantly, a kind soul here (thanks @mrjj) has confirmed it does work, but can only test with Qt 5.14.2 under both Windows & Linux Mint.

    There is a 10-year-old bug https://bugreports.qt.io/browse/QTBUG-8593, never addressed, reporting similar for Linux only; I do not know whether that has any relevance to now.

    I am wondering whether another kind soul can test under, say, Ubuntu with Qt > 5.12.2 and tell me whether it does work there? Many thanks. At a future point I will move to Ubuntu 20.04 + whatever later Qt comes with it.

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      Can you provide a minimal compilable example ?
      That will allow people to just grab your code, build and test in the same conditions as you.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      JonBJ 1 Reply Last reply
      0
      • SGaistS SGaist

        Hi,

        Can you provide a minimal compilable example ?
        That will allow people to just grab your code, build and test in the same conditions as you.

        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by JonB
        #3

        @SGaist
        In writing a standalone example, I have discovered what is causing this behaviour. But it's so strange I have no idea why!

        This presumably means it has nothing to do with Linux or Qt version, and the issue it not limited to background colour. Which means I could raise a slightly different topic title, but we are here, so...

        Here is a dead-simple standalone illustrating issue. Run by me under Ubuntu 19.04 with accompanying Qt 5.12.2, but now presumed to happen on any platform/Qt version?

        #include <QApplication>
        #include <QLineEdit>
        #include <QSpinBox>
        #include <QVBoxLayout>
        #include <QWidget>
        
        int main(int argc, char *argv[])
        {
            QApplication a(argc, argv);
            QWidget w;
            QVBoxLayout layout;
            w.setGeometry(100, 100, 200, 200);
            w.setLayout(&layout);
        
            // commenting in/out next line makes `QLineEdit` in `QSpinBox` ignore/respect its own stylesheet colors
            // yet standalone `QLineEdit` respects its own stylesheet colors in either case
            w.setStyleSheet("background-color: yellow; color: green;");
        
            QLineEdit lineEdit;
            layout.addWidget(&lineEdit);
            lineEdit.setText("99999");
            // standalone `QLineEdit` always respects stylesheet, and behaves correctly
            lineEdit.setStyleSheet("background-color: cyan; color: red;");
        
            QSpinBox spinBox;
            layout.addWidget(&spinBox);
            QLineEdit *spinLineEdit = spinBox.findChild<QLineEdit *>();
            spinBox.setMaximum(99999);
            spinBox.setValue(99999);
            // `QLineEdit` in `QSpinBox` respects stylesheet, and behaves correctly, *ONLY IF ANCESTOR `QWidget` DOES NOT SPECIFY COLORS*
            // if parent `QWidget` does specify colors, next line has no effect on it!
            spinLineEdit->setStyleSheet("background-color: cyan; color: red;");
        
            w.show();
            return a.exec();
        }
        

        Comments describe behaviour.

        • With parent/ancestor w.setStyleSheet("background-color: yellow; color: green;"); line enabled, QSpinBox alone goes wrong while comparison QLineEdit works correctly, screenshot:

        Screenshot from 2020-04-17 09-01-59.png

        • With parent/ancestor // w.setStyleSheet("background-color: yellow; color: green;"); line commented out, both behave correctly, screenshot:

        Screenshot from 2020-04-17 09-02-33.png

        Can anyone explain this, please?

        [And btw if I set the stylesheet on the QSpinBox itself rather than its embedded line edit then that does work regardless of ancestor widget colours, but that is not what I want. It is an issue on the QlineEdit embedded in a QSpinBox only.]

        1 Reply Last reply
        0
        • JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #4

          I didn't get any takers here (other than @mrjj) :( Reported as Qt bug at https://bugreports.qt.io/browse/QTBUG-83961.

          P 1 Reply Last reply
          2
          • JonBJ JonB

            I didn't get any takers here (other than @mrjj) :( Reported as Qt bug at https://bugreports.qt.io/browse/QTBUG-83961.

            P Offline
            P Offline
            Phil K
            wrote on last edited by Phil K
            #5

            @JonB I had a similar need in terms of wanting the background of my spinbox delegate to reflect the background color of the current row when alternating row colors are used by the view. The way I solved it is below. Not using style sheets here, but rather I grab the palette of the app (which is themed elsewhere) and then adjust the palette of the spinbox's QLineEdit. Works.

            QWidget *SpinboxDelegate::createEditor(
                    QWidget *parent, const QStyleOptionViewItem & option, const QModelIndex & index) const
            {
                Q_UNUSED(option);
                QSpinBox *editor = new QSpinBox(parent);
                editor->setAlignment(Qt::AlignRight);
                editor->setAutoFillBackground(true);
                // hack to grab protected QLineEdit from QSpinBox parent
                auto line_editors = editor->findChildren<QLineEdit*>();
                QLineEdit *line_editor = !line_editors.empty() ? line_editors.front() : nullptr;
                if (line_editor && index.isValid()) {
                    // line editor background color set to current row background color
                    const QPalette app_palette = qApp->palette();
                    QPalette palette = line_editor->palette();
                    palette.setColor(QPalette::Base, index.row() % 2 ?
                                         app_palette.color(QPalette::AlternateBase) :
                                         app_palette.color(QPalette::Base));
                    line_editor->setPalette(palette);
                }
                editor->setFrame(false);
                editor->setMinimum(-100000);
                editor->setMaximum(100000);
                return editor;
            }
            
            1 Reply Last reply
            2
            • P Offline
              P Offline
              Phil K
              wrote on last edited by
              #6

              I'm amending my code snippet above so that it works properly with scroll areas and tree views. The row of the QModelIndex won't tell you the row needed for accurate alternate coloring. i.e. you need the row relative to the top of the scroll area and, for item views, the data above you might also be in various states of expand/collapse.

              In digging through the Qt code, I notice that the QStyleOptionViewItem delivered to delegate's createEditor does not carry the feature QStyleOptionViewItem::Alternate. That bit is added by the tree view in drawRow. This is too bad since that bit could directly tell us whether or not we're on an alternate row. That bit is sent into the delegate's paint function however, so you could play with it there.

              QWidget *SpinboxDelegate::createEditor(
                      QWidget *parent, const QStyleOptionViewItem & option, const QModelIndex & index) const
              {
                  QSpinBox *editor = new QSpinBox(parent);
                  editor->setAlignment(Qt::AlignRight);
                  editor->setAutoFillBackground(true);
                  const QAbstractItemView *view = qobject_cast<const QAbstractItemView*>(option.widget);
                  if (view) {
                      // determine row that the index is sitting on relative to top of scroll area
                      const QRect rect = view->visualRect(index);
                      const int pos = view->verticalScrollBar()->value();
                      const int row = pos + (rect.top() / rect.height());
                      // hack to grab protected QLineEdit from QSpinBox parent
                      auto line_editors = editor->findChildren<QLineEdit*>();
                      QLineEdit *line_editor = !line_editors.empty() ? line_editors.front() : nullptr;
                      if (line_editor && index.isValid()) {
                          // line editor background color set to current row background color
                          const QPalette app_palette = qApp->palette();
                          QPalette palette = line_editor->palette();
                          palette.setColor(QPalette::Base, row % 2 ?
                                               app_palette.color(QPalette::AlternateBase) :
                                               app_palette.color(QPalette::Base));
                          line_editor->setPalette(palette);
                      }
                  }
                  editor->setFrame(false);
                  editor->setMinimum(-100000);
                  editor->setMaximum(100000);
                  return editor;
              
              1 Reply Last reply
              0
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #7

                Hi,

                I currently wonder whether it's something that should be available there. Did you check the bug report system to see if there's something related ? If not, you could open a feature request.

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                P JonBJ 2 Replies Last reply
                0
                • SGaistS SGaist

                  Hi,

                  I currently wonder whether it's something that should be available there. Did you check the bug report system to see if there's something related ? If not, you could open a feature request.

                  P Offline
                  P Offline
                  Phil K
                  wrote on last edited by
                  #8

                  @SGaist In the context of delegates, the editor is created by the QAbstractItemView on this line of code and if you trace it back, you can see that openEditor is not adding the option features that drawRow adds in the QTreeView derivation for the paint calls. Not sure it would be easy to add that style feature on that abstract class. Perhaps.

                  1 Reply Last reply
                  0
                  • SGaistS SGaist

                    Hi,

                    I currently wonder whether it's something that should be available there. Did you check the bug report system to see if there's something related ? If not, you could open a feature request.

                    JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on last edited by JonB
                    #9

                    @SGaist
                    Are you addressing this to @Phil-K or to myself?

                    I wrote earlier that I reported this bug as https://bugreports.qt.io/browse/QTBUG-83961 9 months ago, but haven't had any takers :) [Other than 2 non-expert replies, to which I responded as both were wrong!]

                    I can't say for @Phil-K's response now. But, at least in my non-edit case, one should not need to write some set of code. There is just something fundamentally wrong in Qt's internal code for handling the QLineEdit part of a QSpinBox, at least so far as my coloring via stylesheet is concerned.

                    1 Reply Last reply
                    0
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      At @Phil-K but somehow I managed to miss the link to the existing report... vertical scrolling is sometimes treacherous.

                      The current answers are indeed inadequate.

                      Interested in AI ? www.idiap.ch
                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                      P 1 Reply Last reply
                      0
                      • SGaistS SGaist

                        At @Phil-K but somehow I managed to miss the link to the existing report... vertical scrolling is sometimes treacherous.

                        The current answers are indeed inadequate.

                        P Offline
                        P Offline
                        Phil K
                        wrote on last edited by Phil K
                        #11

                        I necro'd the thread and went off on a tangent. Scrolling is not relevant to the original problem. The style painter is painting that QSpinBox with a call from paintEvent to drawComplexControl so you would need to trace the drawing code through the style machinery to see what's happening. As a workaround you can set the stylesheet for the QSpinBox instead of the editor, but you'll have to adjust the buttons using the QSpinBox::up-button/::down-button subcontrol selectors. Too bad there isn't a subcontrol css selector for the QLineEdit itself. That would help. Also, I note that the css selectors for children (#qt_spinbox_lineedit or QSpinBox > QLineEdit) indeed don't seem to work in this context, so the drawing code is probably using the spinbox style settings and ignoring the rest.

                        1 Reply Last reply
                        0
                        • P Offline
                          P Offline
                          Phil K
                          wrote on last edited by
                          #12

                          @JonB Here's a fast workaround that you may like. Give the parent widget an object name and set its stylesheet using the #id selector. That will prevent the problematic propagation to the QLineEdit of the QSpinBox. Cheers.

                          #include <QApplication>
                          #include <QLineEdit>
                          #include <QSpinBox>
                          #include <QVBoxLayout>
                          #include <QWidget>
                          
                          int main(int argc, char *argv[])
                          {
                              QApplication a(argc, argv);
                              QWidget w;
                              QVBoxLayout layout;
                              w.setGeometry(100, 100, 200, 200);
                              w.setLayout(&layout);
                              // Use #id selector to prevent propagation
                              w.setObjectName("my_widget");
                              w.setStyleSheet("#my_widget {background-color: yellow; color: green;}");
                          
                              QLineEdit *lineEdit = new QLineEdit;
                              layout.addWidget(lineEdit);
                              lineEdit->setText("50");
                              lineEdit->setStyleSheet("background-color: cyan; color: red;");
                          
                              QSpinBox *spinBox = new QSpinBox;
                              layout.addWidget(spinBox);
                              QLineEdit *spinLineEdit = spinBox->findChild<QLineEdit *>();
                              spinBox->setMaximum(100);
                              spinBox->setMinimum(-100);
                              spinBox->setValue(50);
                              spinLineEdit->setStyleSheet("background-color: blue; color: red;");
                          
                              w.show();
                              return a.exec();
                          }
                          
                          JonBJ 1 Reply Last reply
                          1
                          • P Phil K

                            @JonB Here's a fast workaround that you may like. Give the parent widget an object name and set its stylesheet using the #id selector. That will prevent the problematic propagation to the QLineEdit of the QSpinBox. Cheers.

                            #include <QApplication>
                            #include <QLineEdit>
                            #include <QSpinBox>
                            #include <QVBoxLayout>
                            #include <QWidget>
                            
                            int main(int argc, char *argv[])
                            {
                                QApplication a(argc, argv);
                                QWidget w;
                                QVBoxLayout layout;
                                w.setGeometry(100, 100, 200, 200);
                                w.setLayout(&layout);
                                // Use #id selector to prevent propagation
                                w.setObjectName("my_widget");
                                w.setStyleSheet("#my_widget {background-color: yellow; color: green;}");
                            
                                QLineEdit *lineEdit = new QLineEdit;
                                layout.addWidget(lineEdit);
                                lineEdit->setText("50");
                                lineEdit->setStyleSheet("background-color: cyan; color: red;");
                            
                                QSpinBox *spinBox = new QSpinBox;
                                layout.addWidget(spinBox);
                                QLineEdit *spinLineEdit = spinBox->findChild<QLineEdit *>();
                                spinBox->setMaximum(100);
                                spinBox->setMinimum(-100);
                                spinBox->setValue(50);
                                spinLineEdit->setStyleSheet("background-color: blue; color: red;");
                            
                                w.show();
                                return a.exec();
                            }
                            
                            JonBJ Offline
                            JonBJ Offline
                            JonB
                            wrote on last edited by JonB
                            #13

                            @Phil-K
                            Hi Phil. Yes, I realize what you are doing here, but unfortunately this does not do the job correctly enough for my requirements.

                            Firstly, the result of yours is:
                            Screenshot from 2021-01-26 09-55-56.png

                            Compare that to the correct one I show earlier above. Not surprisingly, while the line edit itself is now correct colors, the spinbox "furniture" around it has now lost the desired background yellow of the whole form and is shown in the default "grey".

                            Secondly, I had to cut mine down to a minimal example. In practice I have a top-level background-colored widget, whose color I want inherited everywhere except when overridden, then I have a potentially-unknown hierarchy of further sub-widgets, and at the bottom I have a QSpinBox. Colored-widget -> widget -> widget -> ... -> spinbox. And I have loads of these QSpinBoxes. Setting the color on the top-level widget by id will limit it to that widget only, and there is no chance of picking out all the direct parent widgets of the child spinboxes for application of some distant, top-level color which may have been specified.

                            The problem, it seems to me, must be addressed on the QSpinBox itself, not higher up the hierarchy. And the issue is that somewhere in the Qt code there is some "unusal" handling of the QSpinBox::lineEdit() such that you cannot get it to respect its own stylesheet rule iff some ancestor does specify colors. Tackling this somehow at a "top-level" widget cannot be the solution. I refer you again to my example which shows that a standalone QLineEdit does behave correctly in this situation, while the QLineEdit internal to a QSpinBox does not in the same situation. This is a QSpinBox-alone issue. Which is what I need resolved or at least explained!

                            P 1 Reply Last reply
                            0
                            • JonBJ JonB

                              @Phil-K
                              Hi Phil. Yes, I realize what you are doing here, but unfortunately this does not do the job correctly enough for my requirements.

                              Firstly, the result of yours is:
                              Screenshot from 2021-01-26 09-55-56.png

                              Compare that to the correct one I show earlier above. Not surprisingly, while the line edit itself is now correct colors, the spinbox "furniture" around it has now lost the desired background yellow of the whole form and is shown in the default "grey".

                              Secondly, I had to cut mine down to a minimal example. In practice I have a top-level background-colored widget, whose color I want inherited everywhere except when overridden, then I have a potentially-unknown hierarchy of further sub-widgets, and at the bottom I have a QSpinBox. Colored-widget -> widget -> widget -> ... -> spinbox. And I have loads of these QSpinBoxes. Setting the color on the top-level widget by id will limit it to that widget only, and there is no chance of picking out all the direct parent widgets of the child spinboxes for application of some distant, top-level color which may have been specified.

                              The problem, it seems to me, must be addressed on the QSpinBox itself, not higher up the hierarchy. And the issue is that somewhere in the Qt code there is some "unusal" handling of the QSpinBox::lineEdit() such that you cannot get it to respect its own stylesheet rule iff some ancestor does specify colors. Tackling this somehow at a "top-level" widget cannot be the solution. I refer you again to my example which shows that a standalone QLineEdit does behave correctly in this situation, while the QLineEdit internal to a QSpinBox does not in the same situation. This is a QSpinBox-alone issue. Which is what I need resolved or at least explained!

                              P Offline
                              P Offline
                              Phil K
                              wrote on last edited by Phil K
                              #14

                              @JonB Well my suggestion is to read the Qt code and find the exact areas where the problem exists and propose a patch on your bug report. I had an old boss many years ago who said "Don't come to me with a problem. Come to me with a problem, three solutions and a recommendation." Good luck.

                              JonBJ 1 Reply Last reply
                              0
                              • P Phil K

                                @JonB Well my suggestion is to read the Qt code and find the exact areas where the problem exists and propose a patch on your bug report. I had an old boss many years ago who said "Don't come to me with a problem. Come to me with a problem, three solutions and a recommendation." Good luck.

                                JonBJ Offline
                                JonBJ Offline
                                JonB
                                wrote on last edited by
                                #15

                                @Phil-K
                                Yes the solution to any question Qt can be read the code and find out for yourself. Difficult when I have never compiled Qt, can't step through the code, and am looking to try to find out why some stylesheet rule is or is not overridden by some inheritance elsewhere, which I'm pretty sure will be convoluted/a minefield to work out. Which is why I raised it as a bug at bugreports, in the hope that someone who maintains that code might post an answer. But not. Thank you for your interest.

                                1 Reply Last reply
                                1

                                • Login

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