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. QComboBox: preventing popup from closing
QtWS25 Last Chance

QComboBox: preventing popup from closing

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 3 Posters 5.5k 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.
  • V Offline
    V Offline
    voltron
    wrote on last edited by
    #1

    I have a QComboBox subclass that supports multiple items selection. Items displayed with the help of custom QStyledItemDelegate. How I can prevent dropdown list from closing when user clicks on items and close it only when mouse leaves dropdown or user clicked outside the dropdown?

    First I tried to reimplement hidePopup() method like this

    void MyCombo::hidePopup()
    {
      if ( !view()->underMouse() )
      {
        QComboBox::hidePopup();
      }
    }
    

    But this works only with Qt 4, seems under Qt 5.5.1 view()->underMouse() returns false even when mouse under popup.

    Next I tried to implement event filter

    bool MyCombo::eventFilter( QObject *object, QEvent *event )
    {
      if( event->type() == QEvent::MouseButtonRelease && object == view() )
      {
        return true;
      }
    
      return QComboBox::eventFilter( object, event );
    }
    

    But stuck as I need to "eat" clicks to prevent popup from closing and in the same time clicks are necessary to change item selection.

    Any ideas how to allow selecting multiple items at once without closing popup?

    P.S. guys, please don't tell me about QListWidget/QListView and other widgets. This topic is about solving specific problem, and not about which widget to use.

    J.HilkJ 1 Reply Last reply
    1
    • V voltron

      I have a QComboBox subclass that supports multiple items selection. Items displayed with the help of custom QStyledItemDelegate. How I can prevent dropdown list from closing when user clicks on items and close it only when mouse leaves dropdown or user clicked outside the dropdown?

      First I tried to reimplement hidePopup() method like this

      void MyCombo::hidePopup()
      {
        if ( !view()->underMouse() )
        {
          QComboBox::hidePopup();
        }
      }
      

      But this works only with Qt 4, seems under Qt 5.5.1 view()->underMouse() returns false even when mouse under popup.

      Next I tried to implement event filter

      bool MyCombo::eventFilter( QObject *object, QEvent *event )
      {
        if( event->type() == QEvent::MouseButtonRelease && object == view() )
        {
          return true;
        }
      
        return QComboBox::eventFilter( object, event );
      }
      

      But stuck as I need to "eat" clicks to prevent popup from closing and in the same time clicks are necessary to change item selection.

      Any ideas how to allow selecting multiple items at once without closing popup?

      P.S. guys, please don't tell me about QListWidget/QListView and other widgets. This topic is about solving specific problem, and not about which widget to use.

      J.HilkJ Offline
      J.HilkJ Offline
      J.Hilk
      Moderators
      wrote on last edited by J.Hilk
      #2

      @voltron

      My suggestions:

      event->button() == Qt::LeftButton
      

      and

      event->button() == Qt::RightButton
      

      Make the selection with the left mouse button and hide it when pressed the right button!?

      Edit: fixed typo Qt::LeftButton -> Qt::RightButton.


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      mrjjM 1 Reply Last reply
      1
      • J.HilkJ J.Hilk

        @voltron

        My suggestions:

        event->button() == Qt::LeftButton
        

        and

        event->button() == Qt::RightButton
        

        Make the selection with the left mouse button and hide it when pressed the right button!?

        Edit: fixed typo Qt::LeftButton -> Qt::RightButton.

        mrjjM Offline
        mrjjM Offline
        mrjj
        Lifetime Qt Champion
        wrote on last edited by mrjj
        #3

        Hi
        This one works
        https://github.com/yiminyangguang520/qt/tree/master/QMultiComboBoxDemo

        alt text

        Note. Its against most platform's user interface guidelines.

        1 Reply Last reply
        3
        • V Offline
          V Offline
          voltron
          wrote on last edited by
          #4

          Still no luck with this. As I need to handle right mouse button click too, I can't use right-clicks to close popup.

          I tried to filter clicks on the lineedit and outside popup using following code

          bool MyCombo::eventFilter(QObject *object, QEvent *event)
          {
            if (event->type() == QEvent::MouseButtonRelease)
            {
              if (static_cast<QMouseEvent *>( event )->button() == Qt::RightButton)
              { // "eat" rightclicks
                return true;
              }
          
              if (object == lineEdit())
              { // show popup when user clicks on the combobox's lineedit
                showPopup();
              }
              if(object != view() && object != view()->window())
              { / hide popup when user clicks outside it
                hidePopup();
              }
            }
            return false;
          }
          

          but it does not work as expected, popup closed immediatelly after clicking on the any item and clicking on the lineedit does nothing too. Any ideas what can be wrong and how to fix it?

          J.HilkJ 1 Reply Last reply
          0
          • V voltron

            Still no luck with this. As I need to handle right mouse button click too, I can't use right-clicks to close popup.

            I tried to filter clicks on the lineedit and outside popup using following code

            bool MyCombo::eventFilter(QObject *object, QEvent *event)
            {
              if (event->type() == QEvent::MouseButtonRelease)
              {
                if (static_cast<QMouseEvent *>( event )->button() == Qt::RightButton)
                { // "eat" rightclicks
                  return true;
                }
            
                if (object == lineEdit())
                { // show popup when user clicks on the combobox's lineedit
                  showPopup();
                }
                if(object != view() && object != view()->window())
                { / hide popup when user clicks outside it
                  hidePopup();
                }
              }
              return false;
            }
            

            but it does not work as expected, popup closed immediatelly after clicking on the any item and clicking on the lineedit does nothing too. Any ideas what can be wrong and how to fix it?

            J.HilkJ Offline
            J.HilkJ Offline
            J.Hilk
            Moderators
            wrote on last edited by J.Hilk
            #5

            @voltron
            stupid question of me, but you don't show it in your code.
            You do call installEventFilter and not just declare it, right?

            additionally you could add event->accept() so that the event is not passed to the parent.


            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


            Q: What's that?
            A: It's blue light.
            Q: What does it do?
            A: It turns blue.

            V 1 Reply Last reply
            0
            • J.HilkJ J.Hilk

              @voltron
              stupid question of me, but you don't show it in your code.
              You do call installEventFilter and not just declare it, right?

              additionally you could add event->accept() so that the event is not passed to the parent.

              V Offline
              V Offline
              voltron
              wrote on last edited by
              #6

              @J.Hilk said in QComboBox: preventing popup from closing:

              @voltron
              stupid question of me, but you don't show it in your code.
              You do call installEventFilter and not just declare it, right?

              Sure, installEventFilter called in the costructor

              MyCombo::MyCombo( QWidget *parent ) : QComboBox( parent )
              {
                ...
                view()->installEventFilter( this );
                view()->window()->installEventFilter( this );
                view()->viewport()->installEventFilter( this );
              }
              

              additionally you could add event->accept() so that the event is not passed to the parent.

              Thanks, will give it a try.

              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