QComboBox: preventing popup from closing



  • 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.



  • @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.


  • Qt Champions 2016

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

    alt text

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



  • 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?



  • @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.



  • @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.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.