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. [SOLVED] Stylize using CSS and editable QComboBox's completions list view
Forum Updated to NodeBB v4.3 + New Features

[SOLVED] Stylize using CSS and editable QComboBox's completions list view

Scheduled Pinned Locked Moved General and Desktop
20 Posts 3 Posters 15.3k Views 1 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.
  • napajejenunedk0N Offline
    napajejenunedk0N Offline
    napajejenunedk0
    wrote on last edited by
    #1

    @
    QListView {
    background: red;
    }
    @

    does the trick, but in very global level. I want to stylize only the list view of the QComboBox completion list. Something like:
    @
    QComboBox QListView,
    QComboBox > QListView,
    QComboBox QLineEdit QListView, /* the combo box's editor */
    QComboBox > QLineEdit > QListView,
    {
    ...
    }
    @

    All of these don't work. Any suggestions how to stylize the QComboBox's completion list view only?

    1 Reply Last reply
    0
    • raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on last edited by
      #2

      are you sure that
      @
      QComboBox QListView {
      ...
      }
      @

      is not working? Because i just tried it and it works. I think you may have another style definition which overrides yours.

      Alternatively you can try to style QComboBoxListView class.

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      1 Reply Last reply
      0
      • napajejenunedk0N Offline
        napajejenunedk0N Offline
        napajejenunedk0
        wrote on last edited by
        #3

        @
        QComboBox QListView {
        background: red;
        }
        @

        Stylizes the drop-down of the combobox the same way:
        @
        QComboBox QAbstractItemView {
        ...
        }
        @

        ... does. But I'm trying to stylize the completions list, not the choices list. The title of the topic says:

        bq. Stylize using CSS and editable QComboBox’s completions list view

        ... not the drop down that lists all possible combobox choices. So, when you have a QCompleter set to the combobox and start typing in the combobox, a completions' list is displayed the same way the choices list is displayed. But the completions list is not stylized.

        1 Reply Last reply
        0
        • raven-worxR Offline
          raven-worxR Offline
          raven-worx
          Moderators
          wrote on last edited by
          #4

          ah sorry for that.
          In this case you have to do the following:
          @
          completer->popup()->setObjectName("MyCompleterList");
          @
          and in the stylesheet:
          @
          QAbstractItemView[objectName="MyCompleterList"] {
          ...
          }
          @
          since i see no other styling possibility.
          Note that the popup has no parent set. It's just a widget with the popup window flag set.

          --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
          If you have a question please use the forum so others can benefit from the solution in the future

          1 Reply Last reply
          0
          • napajejenunedk0N Offline
            napajejenunedk0N Offline
            napajejenunedk0
            wrote on last edited by
            #5

            Bingo. Thanks. One more question:
            @
            QAbstractItemView[objectName="MyCompleterList"]::item {
            height: ...;
            }
            @

            ... doesn't work. Any suggestions?

            1 Reply Last reply
            0
            • raven-worxR Offline
              raven-worxR Offline
              raven-worx
              Moderators
              wrote on last edited by
              #6

              i'm not sure if that's intended to work at all. But you can try min-height. If that's not working setting the size of view items is not possible...

              --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
              If you have a question please use the forum so others can benefit from the solution in the future

              1 Reply Last reply
              0
              • U Offline
                U Offline
                Uwe Kindler
                wrote on last edited by
                #7

                Hi,

                we also had the same problem styling the completer popup and could solve the problem by implementing our own completer class that we derived from QCompleter. The problem seems to be, that the completer popup does not use a QStyledItemDelegate and thus does not support styling of single items. We solved the problem by assigning a QStyledItemDelegate to the item view after the model has been assigned to the completer:

                @
                /**

                • Private data class (pimpl)
                  /
                  struct CompleterPrivate
                  {
                  QStyledItemDelegate
                  CompleterDelegate;
                  };

                CCompleter::CCompleter(QObject* parent)
                : QCompleter(parent),
                d(new CompleterPrivate())
                {
                d->CompleterDelegate = new QStyledItemDelegate(this);
                popup()->setObjectName("completerPopup");
                }

                CCompleter::~CCompleter()
                {
                delete d;
                }

                void CCompleter::setModel(QAbstractItemModel* model)
                {
                QCompleter::setModel(model);
                popup()->setItemDelegate(d->CompleterDelegate);
                }
                @

                1 Reply Last reply
                0
                • napajejenunedk0N Offline
                  napajejenunedk0N Offline
                  napajejenunedk0
                  wrote on last edited by
                  #8

                  Yes, I've already tried using min-height - doesn't work.

                  Thank you for the extensive help. I was examining the source code of the QLineEdit and QComboBox to find whether the QAbstractItemView is created there and if so, does it have an object name. But the actual holder of the QAbstractItemView as you've pointed out is the QCompleter, which probably assigns the parent (which is a QWidget subclass) of the QCompleter (which is QObject subclass) to be the parent of the view as well and using QComboBox QAbstractItemView descendant css selector doesn't apply the given stylesheet to the completions list the same way it does for the choices list.

                  Thanks.

                  1 Reply Last reply
                  0
                  • napajejenunedk0N Offline
                    napajejenunedk0N Offline
                    napajejenunedk0
                    wrote on last edited by
                    #9

                    Uwe Kindler: thank you, I will try it out. The solution you propose is the same as the one used for enabling stylizing on QComboBox as a whole:
                    http://stackoverflow.com/questions/13308341/qcombobox-abstractitemviewitem

                    1 Reply Last reply
                    0
                    • raven-worxR Offline
                      raven-worxR Offline
                      raven-worx
                      Moderators
                      wrote on last edited by
                      #10

                      well...the subclassing of QCompleter is unnecessary extra work since you already get what you need with the popup() (which is a simple QListView btw.) method.
                      You can set your delegate also directly there.

                      @
                      class MyCompleterDelegate : public QStyledItemDelegate
                      {
                      public:
                      MyCompleterDelegate(QObject* parent = 0) : QStyledItemDelegate(parent)
                      {
                      }

                      QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const
                      {
                            QSize size = QStyledItemDelegate::sizeHint(option, index);
                            size.setHeight( ... );
                            return size;
                      }
                      

                      }
                      @

                      and set this delegate

                      @
                      completer->popup()->setItemDelegate(new MyCompleterDelegate(completer->popup())); //or if you directly set a "empty" QStyledItemDelegate instead of custom deleagte
                      @

                      thats all ;)

                      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                      If you have a question please use the forum so others can benefit from the solution in the future

                      1 Reply Last reply
                      0
                      • napajejenunedk0N Offline
                        napajejenunedk0N Offline
                        napajejenunedk0
                        wrote on last edited by
                        #11

                        I've tried the QCompleter subclass approach and the following css:

                        So, I presume I should make a Q_PROPERTY, so that I can access this height from css?

                        I took the subclass approach the same way I've made QComboBox stylable:
                        @
                        StylablePopupCompleter::StylablePopupCompleter( QObject* parent )
                        : QCompleter( parent )
                        {
                        this->makePopupStylable();
                        }

                        StylablePopupCompleter::StylablePopupCompleter( QAbstractItemModel* model, QObject* parent )
                        : QCompleter( model, parent )
                        {
                        this->makePopupStylable();
                        }

                        #ifndef QT_NO_STRINGLISTMODEL
                        StylablePopupCompleter::StylablePopupCompleter( const QStringList& completions, QObject* parent )
                        : QCompleter( completions, parent )
                        {
                        this->makePopupStylable();
                        }
                        #endif

                        StylablePopupCompleter::~StylablePopupCompleter()
                        {
                        }

                        void StylablePopupCompleter::makePopupStylable()
                        {
                        QAbstractItemView* const completionsView = this->popup();
                        completionsView->setItemDelegate( new QStyledItemDelegate( completionsView ) );
                        }

                        @

                        1 Reply Last reply
                        0
                        • U Offline
                          U Offline
                          Uwe Kindler
                          wrote on last edited by
                          #12

                          Well, I thought my example was quite clear (clear like german Klossbruehe) and you just needed to copy my code. So here we go again:

                          You can only style classes that are derived from QWidget - so no - you can't style QCompleter directly - never

                          You can style the QCompleter popup because it is an QAbstractItemView (derived from QWidget)

                          To style the popup (the QAbstractItemView) you need a CSS selector to style only the completer popups

                          That was the reason I gave the popup the object name "completerPopup"

                          Now you can use CSS to stlye all QAbstractItemViews with name "completerPopup"

                          You need to set the item delegate after the model has been set.

                          You need to set the item delegate each time a new model is assigned because it seems that internally a new item view or delegate is created if a new model is assigned

                          This was the reason I set the delegate in the setModel() function because this ensures that each time a new model is assigned, the item delegate will be updated.

                          The solution from raven-worx is not what you want because it sets the height hardcoded in the delegate and is not stylable via CSS.

                          C++ Code:
                          @ /**
                          * Private data class (pimpl)
                          /
                          struct CompleterPrivate
                          {
                          QStyledItemDelegate
                          CompleterDelegate;
                          };

                          CCompleter::CCompleter(QObject* parent)
                           : QCompleter(parent),
                             d(new CompleterPrivate())
                          {
                           d->CompleterDelegate = new QStyledItemDelegate(this);
                           popup()->setObjectName("completerPopup");
                          }
                           
                           
                          CCompleter::~CCompleter()
                          {
                           delete d;
                          }
                           
                           
                          void CCompleter::setModel(QAbstractItemModel* model)
                          {
                           QCompleter::setModel(model);
                           popup()->setItemDelegate(d->CompleterDelegate);
                          }
                          

                          @

                          Example CSS Stylesheet:

                          @
                          QAbstractItemView#completerPopup
                          {
                          border: 1px solid rgb(81, 81, 81);
                          padding: 1px;
                          }

                          QAbstractItemView#completerPopup::item
                          {
                          padding-top: 2px;
                          padding-bottom: 2px;
                          }
                          @

                          1 Reply Last reply
                          0
                          • napajejenunedk0N Offline
                            napajejenunedk0N Offline
                            napajejenunedk0
                            wrote on last edited by
                            #13

                            bq. That was the reason I gave the popup the object name “completerPopup”

                            If you have looked better in my code you will notice that the class is named:
                            StylablePopup Completer not StylableCompleter - since only the visual element is stylable. And I know QWidget-based classes are stylizable only.

                            About the setModel - thank you for the remark, since changing the model, changes the delegate as well.

                            1 Reply Last reply
                            0
                            • U Offline
                              U Offline
                              Uwe Kindler
                              wrote on last edited by
                              #14

                              I think you misunderstood the meaning of object name. Object name does not mean class name - so it does not matter if you name your class StylablePopupCompleter, StylableCompleter or FlyingPigCompleter. Object name means that you call the method setObjectName of the popup to give all popups an object name that you can use from CSS as ID selector.

                              C++ Code:

                              @popup()->setObjectName("completerPopup");@

                              Now you can use the CSS ID selector to style all QAbtractItemViews whose object name is completerPopup.

                              CSS Code:

                              @QAbstractItemView#completerPopup
                              {
                              ...
                              }
                              @

                              bq. So, I presume I should make a Q_PROPERTY, so that I can access this height from css?

                              Which class should get this Q_PROPERTY?

                              1 Reply Last reply
                              0
                              • napajejenunedk0N Offline
                                napajejenunedk0N Offline
                                napajejenunedk0
                                wrote on last edited by
                                #15

                                No, I understand the meaning of object name very well, and I know that the object name could be used to access QWidget-based stylable instances through the css. Your remark:

                                bq. That was the reason I gave the popup the object name “completerPopup”

                                Targets that you think I want to stylize the QCompleter, not its popup since I've named my QCompleter subclass StylablePopupCompleter. But my point is that the completer has StylablePopup. I don't mean that the QCompleter is stylable but its popup. That's why I haven't named it StylableCompleter but StylePopupCompleter.

                                @
                                QAbstractItemView#completerPopup
                                {
                                ...
                                }
                                @

                                You are wrong here.
                                @
                                QAbstractItemView #completerPopup
                                @

                                You use css descendant selector to access the #completerPopup but #completerPopup is not a descendant of QAbstractItemView, it is QAbstractItemView, so raven-worx is correct in this case:
                                @
                                QAbstractItemView[objectName="MyCompleterList"] {
                                ...
                                }
                                @

                                Thank you for the help.

                                1 Reply Last reply
                                0
                                • U Offline
                                  U Offline
                                  Uwe Kindler
                                  wrote on last edited by
                                  #16

                                  bq. You use css descendant selector to access the #completerPopup but #completerPopup is not a descendant of QAbstractItemView, it is QAbstractItemView, so raven-worx is correct in this case:

                                  You are wrong again. You really should read the Qt CSS documentation ;O):

                                  "http://doc.qt.digia.com/4.7/stylesheet-syntax.html":http://doc.qt.digia.com/4.7/stylesheet-syntax.html

                                  This is was the QT reference says if you follow the link:

                                  bq. ID Selector QPushButton#okButton Matches all QPushButton instances whose object name is okButton.

                                  So you never need to do something like QAbstractItemView[objectName="MyCompleterList"] because you can alway use # to select an QWidget with a certain object name.

                                  Btw. my code was copied from a real "world application":http://www.cetoni.de/products/software/qmixelements.html we have implemented here and therfore I can assure you that it works:

                                  1 Reply Last reply
                                  0
                                  • raven-worxR Offline
                                    raven-worxR Offline
                                    raven-worx
                                    Moderators
                                    wrote on last edited by
                                    #17

                                    guys ... you are both talking about the same thing.
                                    when there is a space before the # is treated as a descendant, otherwise not.
                                    It doesn't matter you both mean the same thing ... i think there is just a misunderstanding with each other ;)

                                    Note: using [objectName="XXX"] or #XXX is the same thing ... absolutely no difference.

                                    --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                                    If you have a question please use the forum so others can benefit from the solution in the future

                                    1 Reply Last reply
                                    0
                                    • U Offline
                                      U Offline
                                      Uwe Kindler
                                      wrote on last edited by
                                      #18

                                      Ah - ok, that was new to me.

                                      Could you please provide a link to the Qt documentation where I can find some details. I have searched the Qt CSS documentation but have not found any place where # is used as a descendant selector.

                                      I only found this one

                                      http://doc.qt.digia.com/4.7/stylesheet-syntax.html

                                      bq. Descendant Selector QDialog QPushButton Matches all instances of QPushButton that are descendants (children, grandchildren, etc.) of a QDialog.

                                      So nothing about # as descendant selector. Strange?!?

                                      1 Reply Last reply
                                      0
                                      • raven-worxR Offline
                                        raven-worxR Offline
                                        raven-worx
                                        Moderators
                                        wrote on last edited by
                                        #19

                                        the # is no descendant selector ... but the space is. # is always the objectName (any widget).

                                        --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                                        If you have a question please use the forum so others can benefit from the solution in the future

                                        1 Reply Last reply
                                        0
                                        • napajejenunedk0N Offline
                                          napajejenunedk0N Offline
                                          napajejenunedk0
                                          wrote on last edited by
                                          #20

                                          Exactly, the strange thing was that:
                                          @
                                          QAbstractItemView #completerPopup
                                          @

                                          didn't work but:
                                          @
                                          QAbstractItemView#completerPopup
                                          @

                                          worked.

                                          Ok, clarified that case. Sorry, Uwe.
                                          Many thanks Uwe, raven for the extensive and detailed answers.

                                          1 Reply Last reply
                                          0

                                          • Login

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