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. How to keep showing the QCombobox popup
Forum Updated to NodeBB v4.3 + New Features

How to keep showing the QCombobox popup

Scheduled Pinned Locked Moved Solved General and Desktop
9 Posts 2 Posters 3.1k 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.
  • R Offline
    R Offline
    RichardW
    wrote on last edited by
    #1

    Hi,
    I'm writing a qcombobox to show a table in popup.
    I create a QTableWidget and use setmodel(table->model()) and setView(table) to set the popup to show a table. But when I click a tableItem in this table, the popup hide automatically. I wonder how to keep showing the popup unless click the toolbutton of combobox or focus out.
    Thanks.

    1 Reply Last reply
    0
    • C Offline
      C Offline
      CPPUIX
      wrote on last edited by
      #2

      Hi,

      Here's a suggestion:

      Try using QComboBox::showPopup() by connecting it to QComboBox::activated(int index).

      The behavior you're talking about is the default, and my suggestion makes it appear again when you click an item on your comboBox popup.

      here's how to connect showPopup() to activated():

      connect(ui->comboBox,&QComboBox::activated,ui->comboBox,&QComboBox::showPopup);
      

      This has a problem, the popup will appear based on the activated index, meaning the activated index will be on top of the combobox instead of the first index as it normally does, here's how it looks:

      popuppreventdisappear.gif

      To fix that, you could use on_comboBox_activated, and set the current index of the combo box to 0 before calling showPopup():

      void Form::on_comboBox_activated(int index)
      {
          ui->comboBox->setCurrentIndex(0);
          ui->comboBox->showPopup();
      }
      

      That still leaves another problem, the popup will flicker because it's hiding and then popping up again.

      I do not know how to fix that yet, one idea is to intercept the popup's hide event, but I do not know how to apply it yet.

      R 1 Reply Last reply
      0
      • C CPPUIX

        Hi,

        Here's a suggestion:

        Try using QComboBox::showPopup() by connecting it to QComboBox::activated(int index).

        The behavior you're talking about is the default, and my suggestion makes it appear again when you click an item on your comboBox popup.

        here's how to connect showPopup() to activated():

        connect(ui->comboBox,&QComboBox::activated,ui->comboBox,&QComboBox::showPopup);
        

        This has a problem, the popup will appear based on the activated index, meaning the activated index will be on top of the combobox instead of the first index as it normally does, here's how it looks:

        popuppreventdisappear.gif

        To fix that, you could use on_comboBox_activated, and set the current index of the combo box to 0 before calling showPopup():

        void Form::on_comboBox_activated(int index)
        {
            ui->comboBox->setCurrentIndex(0);
            ui->comboBox->showPopup();
        }
        

        That still leaves another problem, the popup will flicker because it's hiding and then popping up again.

        I do not know how to fix that yet, one idea is to intercept the popup's hide event, but I do not know how to apply it yet.

        R Offline
        R Offline
        RichardW
        wrote on last edited by
        #3

        @Abderrahmene_Rayene Thanks for your suggestion. I'm now trying to solve the flicker problem by override the hidePopup() function of QCombobox with no code and use my own function to response the focus out event. But by this way, the whole ui stucked except the table just like using exec() which means that I even cannot focus out of the table. Perhaps there is another way to solve it.

        C 1 Reply Last reply
        0
        • R RichardW

          @Abderrahmene_Rayene Thanks for your suggestion. I'm now trying to solve the flicker problem by override the hidePopup() function of QCombobox with no code and use my own function to response the focus out event. But by this way, the whole ui stucked except the table just like using exec() which means that I even cannot focus out of the table. Perhaps there is another way to solve it.

          C Offline
          C Offline
          CPPUIX
          wrote on last edited by
          #4

          @RichardW said in How to keep showing the QCombobox popup:

          I'm now trying to solve the flicker problem by override the hidePopup() function of QCombobox with no code and use my own function to response the focus out event.

          Could you share exactly how you're doing that? I would like to test it on my own and see if I can work it out.

          Thanks!

          R 1 Reply Last reply
          0
          • C CPPUIX

            @RichardW said in How to keep showing the QCombobox popup:

            I'm now trying to solve the flicker problem by override the hidePopup() function of QCombobox with no code and use my own function to response the focus out event.

            Could you share exactly how you're doing that? I would like to test it on my own and see if I can work it out.

            Thanks!

            R Offline
            R Offline
            RichardW
            wrote on last edited by RichardW
            #5

            @Abderrahmene_Rayene sure, simply like this:

            .h:
            class TableBox : public QComboBox
            {
                Q_OBJECT
            public:
                explicit TableBox(QWidget *parent = Q_NULLPTR);
                ~TableBox();
            
                void hidePopup() override{}; // rewrite with nothing
            
            protected:
                bool eventFilter(QObject *obj, QEvent *event);
            
            private:
                QTableWidget *_listTable = nullptr;
            };
            
            
            .cpp:
            TableBox::TableBox(QWidget *parent)
                : QComboBox(parent)
            {
                // setTable
                /* 
                    code to set table 
                */
            
                // deal with event
                this->view()->installEventFilter(this);
            }
            
            bool TableBox::eventFilter(QObject *obj, QEvent *event)
            {
                // try to hide
                if (obj == this->view())
                {
                    if (event->type() == QFocusEvent::FocusOut)
                    {
                        QCombobox::hidePopup();
                    }
                }
            
                return QObject::eventFilter(obj, event);
            }
            

            in my code, the focus out event cannot reach, I have no idea why.
            By the way, this method do not need to connect combobox with showPopup() because hidePopup() never actived.

            C 1 Reply Last reply
            0
            • R RichardW

              @Abderrahmene_Rayene sure, simply like this:

              .h:
              class TableBox : public QComboBox
              {
                  Q_OBJECT
              public:
                  explicit TableBox(QWidget *parent = Q_NULLPTR);
                  ~TableBox();
              
                  void hidePopup() override{}; // rewrite with nothing
              
              protected:
                  bool eventFilter(QObject *obj, QEvent *event);
              
              private:
                  QTableWidget *_listTable = nullptr;
              };
              
              
              .cpp:
              TableBox::TableBox(QWidget *parent)
                  : QComboBox(parent)
              {
                  // setTable
                  /* 
                      code to set table 
                  */
              
                  // deal with event
                  this->view()->installEventFilter(this);
              }
              
              bool TableBox::eventFilter(QObject *obj, QEvent *event)
              {
                  // try to hide
                  if (obj == this->view())
                  {
                      if (event->type() == QFocusEvent::FocusOut)
                      {
                          QCombobox::hidePopup();
                      }
                  }
              
                  return QObject::eventFilter(obj, event);
              }
              

              in my code, the focus out event cannot reach, I have no idea why.
              By the way, this method do not need to connect combobox with showPopup() because hidePopup() never actived.

              C Offline
              C Offline
              CPPUIX
              wrote on last edited by
              #6

              @RichardW I tried to use an eventFilter yesterday to manipulate the hide and focus events, but to no success.

              Overriding hidePopup() with nothing caused the popup to be unable to hide, and never lose focus, unless you hit escape keybutton. It makes it act as a modal dialog or something similar, which is unwanted behavior in this case.

              This gave me another idea, Here it is:

              void hidePopup() override
                  {
                      if(!listTable->geometry().contains(mapFromGlobal(QCursor::pos())))
                          QComboBox::hidePopup();
                  }
              

              What this does is basically only prevent the comboBox popup from hiding when the cursor current position is contained within its geometry, otherwise, calls QComboBox::hidePopup to get the normal behavior.

              Be sure this does not break something else you have or cause unwanted behavior, it's a workaround.

              R 1 Reply Last reply
              0
              • C CPPUIX

                @RichardW I tried to use an eventFilter yesterday to manipulate the hide and focus events, but to no success.

                Overriding hidePopup() with nothing caused the popup to be unable to hide, and never lose focus, unless you hit escape keybutton. It makes it act as a modal dialog or something similar, which is unwanted behavior in this case.

                This gave me another idea, Here it is:

                void hidePopup() override
                    {
                        if(!listTable->geometry().contains(mapFromGlobal(QCursor::pos())))
                            QComboBox::hidePopup();
                    }
                

                What this does is basically only prevent the comboBox popup from hiding when the cursor current position is contained within its geometry, otherwise, calls QComboBox::hidePopup to get the normal behavior.

                Be sure this does not break something else you have or cause unwanted behavior, it's a workaround.

                R Offline
                R Offline
                RichardW
                wrote on last edited by
                #7

                @Abderrahmene_Rayene Thanks for your help! I think this can be the right way to solve my problem. But this make the button of combobox not work too. Are there any method to solve this?

                C 1 Reply Last reply
                0
                • R RichardW

                  @Abderrahmene_Rayene Thanks for your help! I think this can be the right way to solve my problem. But this make the button of combobox not work too. Are there any method to solve this?

                  C Offline
                  C Offline
                  CPPUIX
                  wrote on last edited by
                  #8

                  @RichardW said in How to keep showing the QCombobox popup:

                  But this make the button of combobox not work too

                  That's because I used the table widget geometry, just remove it from the condition, use the comboBox's geomtry instead.

                  void hidePopup() override
                      {
                          if(!geometry().contains(mapFromGlobal(QCursor::pos())))
                              QComboBox::hidePopup();
                      }
                  
                  R 1 Reply Last reply
                  0
                  • C CPPUIX

                    @RichardW said in How to keep showing the QCombobox popup:

                    But this make the button of combobox not work too

                    That's because I used the table widget geometry, just remove it from the condition, use the comboBox's geomtry instead.

                    void hidePopup() override
                        {
                            if(!geometry().contains(mapFromGlobal(QCursor::pos())))
                                QComboBox::hidePopup();
                        }
                    
                    R Offline
                    R Offline
                    RichardW
                    wrote on last edited by
                    #9

                    @Abderrahmene_Rayene Thank you! The problem solved. Have a nice day!

                    1 Reply Last reply
                    0
                    • R RichardW has marked this topic as solved on

                    • Login

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