Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt Creator and other tools
  4. When opening a combox box, always have the first item pre-highlighted and lcoated under the mouse
Forum Updated to NodeBB v4.3 + New Features

When opening a combox box, always have the first item pre-highlighted and lcoated under the mouse

Scheduled Pinned Locked Moved Unsolved Qt Creator and other tools
6 Posts 3 Posters 436 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.
  • S Offline
    S Offline
    SuperSelrak
    wrote on last edited by
    #1

    Hello,

    I have a combo box with the following entries : All, 1, 2, 3, ...., 25.

    As part of the normal usage of the combo box (and, in general, the app I am working on) the user may hop around between 1 and 25 at random (no specific order, they describe totally independent objects).

    However, very often, he will want to go back to "All".

    I noticed that after selecting integer N for example, the combo box will always open to be centered around that value. Could I instead say "Please show the combo box with entry 'All' under the mouse, highlighted and ready to go, at all times ?".

    Like I said, it doesn't matter anyways that N is what is currently under the mouse, as nearby values like N-1 or N+1 are not more interesting than any other value, and have no more chances than any other value of being the next one selected. Rather, the most likely choice when the user opens the combo box is always "All".

    Here is what it looks like with value 8 selected, before opening the combo box :

    cb32fce9-d69c-4af0-b36a-7107bc72d182-image.png

    And here it is after having clicked on the combo box and opened it :

    bc1f8783-c42e-45c7-b431-93227c4dd813-image.png

    1 Reply Last reply
    0
    • S Offline
      S Offline
      SuperSelrak
      wrote on last edited by
      #2

      I have found a simple solution that almost works perfectly. I subclassed QComboBox like this :

      class MyComboBox : public QComboBox
      {
          Q_OBJECT
      
      public:
      
          explicit MyComboBox (QWidget* parent = nullptr)
              : QComboBox(parent) {}
      
          virtual ~MyComboBox () {}
      void showPopup()
      {
          /* Just before opening the combo box,
           * save the current state and instead pre-select index 0. */
          m_tmpIndex = this->currentIndex();
          this->setCurrentIndex(0);
          QComboBox::showPopup();
      }
      void hidePopup()
      {
          QComboBox::hidePopup();
          /* Upon closing the combo box,
           * If the user has actively selected an index other than 0,
           * Use that index.
           * If not (e.g. user clicked outside the combo box to close it,
           * without selecting an index)
           * then re-establish the index as it was before opening the combo box.
           *  */
          if(this->currentIndex() == 0)
          {
              this->setCurrentIndex(m_tmpIndex);
          }
      }
      
      private:
          int m_tmpIndex;
      };
      
      

      Now all it takes a is a double click on the combo box to have index 0 "All" selected. However the double click needs to be slow i.e. with a lot of time between each click. Why is that ?

      JonBJ 1 Reply Last reply
      0
      • S SuperSelrak

        I have found a simple solution that almost works perfectly. I subclassed QComboBox like this :

        class MyComboBox : public QComboBox
        {
            Q_OBJECT
        
        public:
        
            explicit MyComboBox (QWidget* parent = nullptr)
                : QComboBox(parent) {}
        
            virtual ~MyComboBox () {}
        void showPopup()
        {
            /* Just before opening the combo box,
             * save the current state and instead pre-select index 0. */
            m_tmpIndex = this->currentIndex();
            this->setCurrentIndex(0);
            QComboBox::showPopup();
        }
        void hidePopup()
        {
            QComboBox::hidePopup();
            /* Upon closing the combo box,
             * If the user has actively selected an index other than 0,
             * Use that index.
             * If not (e.g. user clicked outside the combo box to close it,
             * without selecting an index)
             * then re-establish the index as it was before opening the combo box.
             *  */
            if(this->currentIndex() == 0)
            {
                this->setCurrentIndex(m_tmpIndex);
            }
        }
        
        private:
            int m_tmpIndex;
        };
        
        

        Now all it takes a is a double click on the combo box to have index 0 "All" selected. However the double click needs to be slow i.e. with a lot of time between each click. Why is that ?

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

        @SuperSelrak
        Be aware that if you have a slot on current index/text changed that will fire during both showPopup() and hidePopup(). Also the user can now never select the "All" item #0 once he has selected another item, is that not an issue?

        S 1 Reply Last reply
        1
        • JonBJ JonB

          @SuperSelrak
          Be aware that if you have a slot on current index/text changed that will fire during both showPopup() and hidePopup(). Also the user can now never select the "All" item #0 once he has selected another item, is that not an issue?

          S Offline
          S Offline
          SuperSelrak
          wrote on last edited by
          #4

          @JonB Thank you for the reminder about the signal that will fire. I actually only care about the activate signal which gets fired only when the index or text has been changed by actual user interaction (and not by program like in the code I wrote for my subclass).

          However no, the other problem you mention does not happen. I don't see why it would, either.

          Also, because of this delay I noticed, I added another good method : use buttons of the mouse ! This is pretty much available on all mice nowadays.

              void mousePressEvent(QMouseEvent * event)
              {
                  if((event->button() == Qt::MiddleButton)
                  || (event->button() == Qt::RightButton))
                  {
                      this->setCurrentIndex(0);
                      this->activated(0);
                  }
                  else
                  {
                      QComboBox::mousePressEvent(event);
                  }
              }
          
          JonBJ 1 Reply Last reply
          0
          • S SuperSelrak

            @JonB Thank you for the reminder about the signal that will fire. I actually only care about the activate signal which gets fired only when the index or text has been changed by actual user interaction (and not by program like in the code I wrote for my subclass).

            However no, the other problem you mention does not happen. I don't see why it would, either.

            Also, because of this delay I noticed, I added another good method : use buttons of the mouse ! This is pretty much available on all mice nowadays.

                void mousePressEvent(QMouseEvent * event)
                {
                    if((event->button() == Qt::MiddleButton)
                    || (event->button() == Qt::RightButton))
                    {
                        this->setCurrentIndex(0);
                        this->activated(0);
                    }
                    else
                    {
                        QComboBox::mousePressEvent(event);
                    }
                }
            
            JonBJ Offline
            JonBJ Offline
            JonB
            wrote on last edited by
            #5

            @SuperSelrak said in When opening a combox box, always have the first item pre-highlighted and lcoated under the mouse:

            However no, the other problem you mention does not happen. I don't see why it would, either.

                if(this->currentIndex() == 0)
                {
                    this->setCurrentIndex(m_tmpIndex);
                }
            

            in hidePopup(). So if during showPopup() something other than "All" was selected, while the popup is visible the user clicks "All" and then this hidePopup() gets called, won't that revert the current index to the m_tmpIndex that was saved from showPopup()?

            1 Reply Last reply
            0
            • Z Offline
              Z Offline
              ziller
              wrote on last edited by
              #6

              Why don't you just add a button "Reset to All" or such, if that is a very common operation?

              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