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. QComboxBox different sizes for button and popup
QtWS25 Last Chance

QComboxBox different sizes for button and popup

Scheduled Pinned Locked Moved Solved General and Desktop
qcombobox
12 Posts 3 Posters 5.2k 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.
  • pablolitoP Offline
    pablolitoP Offline
    pablolito
    wrote on last edited by
    #1

    Hi guys !

    I looking for some help about the QComboBox Widget.

    I'm trying to build a QComboBox with checkboxes (to allow user to select multiple option easily) and in order to save some space on my user interface, I would like to fix the size of the button, and to allow the popup to expand to fit the size of its contents.

    The code I have for now is :

     QComboBox * combo;
     QStandardItem *  item1, * item2;
    
    combo = new QComboBox(ui->tabWidget->widget(0));
    
    this->model = new QStandardItemModel;
    item1 = new QStandardItem;
    item2 = new QStandardItem;
    
    this->model->insertRow(0, item1);
    
    item1->setText("test");
    item1->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
    item1->setData(Qt::Unchecked, Qt::CheckStateRole);
    
    
    item2->setText("test2 long text aha ah ");
    item2->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
    item2->setData(Qt::Unchecked, Qt::CheckStateRole);
    this->model->insertRow(1, item2);
    
    
    combo->setModel(this->model);
    
    combo->view()->setTextElideMode(Qt::ElideNone);
    combo->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
    combo->setMaximumWidth(50);
    
    combo->show();
    
    

    This does the job, except for the size of the popup list.

    So with this code I have a 50 pixels wide button, but I have no clue on how I can make the popup to expand (I tried to access it by calling combo->view() but without any success).

    If someone know how to do this, I would really appreciate some help :)

    Thanks in advance !!
    Pablo

    RatzzR 1 Reply Last reply
    0
    • pablolitoP pablolito

      Hi guys !

      I looking for some help about the QComboBox Widget.

      I'm trying to build a QComboBox with checkboxes (to allow user to select multiple option easily) and in order to save some space on my user interface, I would like to fix the size of the button, and to allow the popup to expand to fit the size of its contents.

      The code I have for now is :

       QComboBox * combo;
       QStandardItem *  item1, * item2;
      
      combo = new QComboBox(ui->tabWidget->widget(0));
      
      this->model = new QStandardItemModel;
      item1 = new QStandardItem;
      item2 = new QStandardItem;
      
      this->model->insertRow(0, item1);
      
      item1->setText("test");
      item1->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
      item1->setData(Qt::Unchecked, Qt::CheckStateRole);
      
      
      item2->setText("test2 long text aha ah ");
      item2->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
      item2->setData(Qt::Unchecked, Qt::CheckStateRole);
      this->model->insertRow(1, item2);
      
      
      combo->setModel(this->model);
      
      combo->view()->setTextElideMode(Qt::ElideNone);
      combo->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
      combo->setMaximumWidth(50);
      
      combo->show();
      
      

      This does the job, except for the size of the popup list.

      So with this code I have a 50 pixels wide button, but I have no clue on how I can make the popup to expand (I tried to access it by calling combo->view() but without any success).

      If someone know how to do this, I would really appreciate some help :)

      Thanks in advance !!
      Pablo

      RatzzR Offline
      RatzzR Offline
      Ratzz
      wrote on last edited by
      #2

      @pablolito
      Are you looking for this http://doc.qt.io/qt-4.8/qcombobox.html#showPopup ?

      --Alles ist gut.

      1 Reply Last reply
      2
      • pablolitoP Offline
        pablolitoP Offline
        pablolito
        wrote on last edited by
        #3

        Actually yes ! thanks a lot ! But I still have a little work to do to get the result I want I guess.

        In the showPopup() method I did a :

        view()->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
        view()->setMinimumWidth(150);
        QComboBox::showPopup();
        

        But I think the setSizeAdjustPolicy() call is not taken into account because the SetMinimumWidth is mandatory if I want the popup list to be resized. is this because of the setMaximumWidth(50); I do previously ?

        Also, if possible I looking to have an automatic resize (150 px is just an example, I would like the popup to fit its content size).

        Do you know how can I achieve this ?

        RatzzR 1 Reply Last reply
        0
        • pablolitoP pablolito

          Actually yes ! thanks a lot ! But I still have a little work to do to get the result I want I guess.

          In the showPopup() method I did a :

          view()->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
          view()->setMinimumWidth(150);
          QComboBox::showPopup();
          

          But I think the setSizeAdjustPolicy() call is not taken into account because the SetMinimumWidth is mandatory if I want the popup list to be resized. is this because of the setMaximumWidth(50); I do previously ?

          Also, if possible I looking to have an automatic resize (150 px is just an example, I would like the popup to fit its content size).

          Do you know how can I achieve this ?

          RatzzR Offline
          RatzzR Offline
          Ratzz
          wrote on last edited by Ratzz
          #4

          @pablolito
          Can you just test with combo->showPopup(); without setting any size .

          --Alles ist gut.

          pablolitoP 1 Reply Last reply
          0
          • RatzzR Ratzz

            @pablolito
            Can you just test with combo->showPopup(); without setting any size .

            pablolitoP Offline
            pablolitoP Offline
            pablolito
            wrote on last edited by
            #5

            @Ratzz

            In this case the button take the size of the popup list, even when the popup is hidden.

            RatzzR 1 Reply Last reply
            0
            • pablolitoP pablolito

              @Ratzz

              In this case the button take the size of the popup list, even when the popup is hidden.

              RatzzR Offline
              RatzzR Offline
              Ratzz
              wrote on last edited by
              #6

              @pablolito
              I did not get exactly what problem you are facing .can you explain your screenshot or so?

              --Alles ist gut.

              1 Reply Last reply
              0
              • pablolitoP Offline
                pablolitoP Offline
                pablolito
                wrote on last edited by
                #7

                Okay.

                I modified a little the code, here is what I have now:

                CheckBoxList::CheckBoxList( QMap<uint32_t, QString> values, QWidget * parent):
                    QComboBox(parent)
                {
                    QMapIterator<uint32_t, QString> it(values);
                
                    QStandardItem *  item1, * item2;
                
                    this->model = new QStandardItemModel;
                    item1 = new QStandardItem;
                    item2 = new QStandardItem;
                
                    this->model->insertRow(0, item1);
                
                    item1->setText("test");
                    item1->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
                    item1->setData(Qt::Unchecked, Qt::CheckStateRole);
                
                
                    item2->setText("test2 long text aha ah ");
                    item2->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
                    item2->setData(Qt::Unchecked, Qt::CheckStateRole);
                    this->model->insertRow(1, item2);
                
                
                    this->setModel(this->model);
                
                    this->view()->setTextElideMode(Qt::ElideNone);
                    this->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
                    this->setMaximumWidth(50);
                    setModel(this->model);
                }
                
                void CheckBoxList::showPopup()
                    {
                        view()->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
                        view()->setMinimumWidth(150);
                        QComboBox::showPopup();
                
                    }
                
                void CheckBoxList::paintEvent(QPaintEvent *)
                    {
                        QStylePainter painter(this);
                        painter.setPen(palette().color(QPalette::Text));
                
                        // draw the combobox frame, focusrect and selected etc.
                        QStyleOptionComboBox opt;
                        initStyleOption(&opt);
                
                        // if no display text been set , use "..." as default
                        if(m_DisplayText.isNull())
                            opt.currentText = "...";
                        else
                            opt.currentText = m_DisplayText;
                        painter.drawComplexControl(QStyle::CC_ComboBox, opt);
                
                        // draw the icon and text
                        painter.drawControl(QStyle::CE_ComboBoxLabel, opt);
                    }
                

                This code give me this result :
                image

                This is what I want : a button which is 50px wide and a popup which is wide enough to display all the items. But for now the popup list is 150px wide (fixed) and I would like to have the width to fit the content of the list.

                Is it clearer ?

                RatzzR 1 Reply Last reply
                0
                • pablolitoP pablolito

                  Okay.

                  I modified a little the code, here is what I have now:

                  CheckBoxList::CheckBoxList( QMap<uint32_t, QString> values, QWidget * parent):
                      QComboBox(parent)
                  {
                      QMapIterator<uint32_t, QString> it(values);
                  
                      QStandardItem *  item1, * item2;
                  
                      this->model = new QStandardItemModel;
                      item1 = new QStandardItem;
                      item2 = new QStandardItem;
                  
                      this->model->insertRow(0, item1);
                  
                      item1->setText("test");
                      item1->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
                      item1->setData(Qt::Unchecked, Qt::CheckStateRole);
                  
                  
                      item2->setText("test2 long text aha ah ");
                      item2->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
                      item2->setData(Qt::Unchecked, Qt::CheckStateRole);
                      this->model->insertRow(1, item2);
                  
                  
                      this->setModel(this->model);
                  
                      this->view()->setTextElideMode(Qt::ElideNone);
                      this->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
                      this->setMaximumWidth(50);
                      setModel(this->model);
                  }
                  
                  void CheckBoxList::showPopup()
                      {
                          view()->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
                          view()->setMinimumWidth(150);
                          QComboBox::showPopup();
                  
                      }
                  
                  void CheckBoxList::paintEvent(QPaintEvent *)
                      {
                          QStylePainter painter(this);
                          painter.setPen(palette().color(QPalette::Text));
                  
                          // draw the combobox frame, focusrect and selected etc.
                          QStyleOptionComboBox opt;
                          initStyleOption(&opt);
                  
                          // if no display text been set , use "..." as default
                          if(m_DisplayText.isNull())
                              opt.currentText = "...";
                          else
                              opt.currentText = m_DisplayText;
                          painter.drawComplexControl(QStyle::CC_ComboBox, opt);
                  
                          // draw the icon and text
                          painter.drawControl(QStyle::CE_ComboBoxLabel, opt);
                      }
                  

                  This code give me this result :
                  image

                  This is what I want : a button which is 50px wide and a popup which is wide enough to display all the items. But for now the popup list is 150px wide (fixed) and I would like to have the width to fit the content of the list.

                  Is it clearer ?

                  RatzzR Offline
                  RatzzR Offline
                  Ratzz
                  wrote on last edited by
                  #8

                  @pablolito
                  You can try with http://doc.qt.io/qt-4.8/qsizepolicy.html#setHorizontalPolicy setting to QSizePolicy::MinimumExpanding .

                  --Alles ist gut.

                  pablolitoP 1 Reply Last reply
                  0
                  • RatzzR Ratzz

                    @pablolito
                    You can try with http://doc.qt.io/qt-4.8/qsizepolicy.html#setHorizontalPolicy setting to QSizePolicy::MinimumExpanding .

                    pablolitoP Offline
                    pablolitoP Offline
                    pablolito
                    wrote on last edited by
                    #9

                    @Ratzz

                    view()->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
                    

                    Does the trick :

                    image

                    But the list is a bit too wide and a bit too long... But it wiil be enough for now !

                    Thanks a lot

                    raven-worxR RatzzR 2 Replies Last reply
                    0
                    • pablolitoP pablolito

                      @Ratzz

                      view()->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
                      

                      Does the trick :

                      image

                      But the list is a bit too wide and a bit too long... But it wiil be enough for now !

                      Thanks a lot

                      raven-worxR Offline
                      raven-worxR Offline
                      raven-worx
                      Moderators
                      wrote on last edited by
                      #10

                      @pablolito
                      this should do the calculation you want:

                      void MyComboBox::showPopup()
                      {
                          //calculate width of all items
                          int width = 0;
                          const int iconWidth = this->iconSize().width() + 4;
                          const QFontMetrics &fontMetrics = this->fontMetrics();
                      
                          for( int i = 0; i < this->count(); ++i )
                          {
                              const int textWidth = fontMetrics.width(this->itemText(i));
                              if (this->itemIcon(i).isNull())
                                  width = (qMax(width, textWidth));
                              else
                                  width = (qMax(width, textWidth + iconWidth));
                          }
                      
                          QStyleOptionComboBox opt;
                          this->initStyleOption(&opt);
                          QSize tmpSize(width, 0);
                          tmpSize = this->style()->sizeFromContents(QStyle::CT_ComboBox, &opt, tmpSize, this);
                      
                          // add width of scrollbar
                          int scrollBarWidth = 0;
                          if( QAbstractScrollArea* scrollArea = qobject_cast<QAbstractScrollArea*>(this->view()) )
                          {
                              QScrollBar* vScrollBar = scrollArea->verticalScrollBar();
                              vScrollBar->ensurePolished();
                      
                              QStyleOptionSlider option;
                                  option.initFrom(vScrollBar);
                                  option.subControls = QStyle::SC_None;
                                  option.activeSubControls = QStyle::SC_None;
                                  option.orientation = Qt::Vertical;
                                  option.minimum = vScrollBar->minimum();;
                                  option.maximum = vScrollBar->maximum();
                                  option.sliderPosition = vScrollBar->sliderPosition();
                                  option.sliderValue = vScrollBar->value();
                                  option.singleStep = vScrollBar->singleStep();
                                  option.pageStep = vScrollBar->pageStep();
                                  option.upsideDown = vScrollBar->invertedAppearance();
                      
                              scrollBarWidth = vScrollBar->style()->pixelMetric( QStyle::PM_ScrollBarExtent, &option, vScrollBar );
                          }
                      
                          // set the width to the popup
                          this->view()->window()->setFixedWidth( qMax(this->width(),tmpSize.width()+scrollBarWidth) );
                      
                          QComboBox::showPopup();
                      }
                      

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

                      pablolitoP 1 Reply Last reply
                      5
                      • pablolitoP pablolito

                        @Ratzz

                        view()->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
                        

                        Does the trick :

                        image

                        But the list is a bit too wide and a bit too long... But it wiil be enough for now !

                        Thanks a lot

                        RatzzR Offline
                        RatzzR Offline
                        Ratzz
                        wrote on last edited by
                        #11

                        @pablolito said:

                        QSizePolicy::MinimumExpanding, QSizePolicy::Preferred

                        Even i have tried in win7 for long text . does not work here .

                            item2->setText("test2 long text aha 123456789012345678901234567890");
                            ui->comboBox->view()->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);

                        --Alles ist gut.

                        1 Reply Last reply
                        0
                        • raven-worxR raven-worx

                          @pablolito
                          this should do the calculation you want:

                          void MyComboBox::showPopup()
                          {
                              //calculate width of all items
                              int width = 0;
                              const int iconWidth = this->iconSize().width() + 4;
                              const QFontMetrics &fontMetrics = this->fontMetrics();
                          
                              for( int i = 0; i < this->count(); ++i )
                              {
                                  const int textWidth = fontMetrics.width(this->itemText(i));
                                  if (this->itemIcon(i).isNull())
                                      width = (qMax(width, textWidth));
                                  else
                                      width = (qMax(width, textWidth + iconWidth));
                              }
                          
                              QStyleOptionComboBox opt;
                              this->initStyleOption(&opt);
                              QSize tmpSize(width, 0);
                              tmpSize = this->style()->sizeFromContents(QStyle::CT_ComboBox, &opt, tmpSize, this);
                          
                              // add width of scrollbar
                              int scrollBarWidth = 0;
                              if( QAbstractScrollArea* scrollArea = qobject_cast<QAbstractScrollArea*>(this->view()) )
                              {
                                  QScrollBar* vScrollBar = scrollArea->verticalScrollBar();
                                  vScrollBar->ensurePolished();
                          
                                  QStyleOptionSlider option;
                                      option.initFrom(vScrollBar);
                                      option.subControls = QStyle::SC_None;
                                      option.activeSubControls = QStyle::SC_None;
                                      option.orientation = Qt::Vertical;
                                      option.minimum = vScrollBar->minimum();;
                                      option.maximum = vScrollBar->maximum();
                                      option.sliderPosition = vScrollBar->sliderPosition();
                                      option.sliderValue = vScrollBar->value();
                                      option.singleStep = vScrollBar->singleStep();
                                      option.pageStep = vScrollBar->pageStep();
                                      option.upsideDown = vScrollBar->invertedAppearance();
                          
                                  scrollBarWidth = vScrollBar->style()->pixelMetric( QStyle::PM_ScrollBarExtent, &option, vScrollBar );
                              }
                          
                              // set the width to the popup
                              this->view()->window()->setFixedWidth( qMax(this->width(),tmpSize.width()+scrollBarWidth) );
                          
                              QComboBox::showPopup();
                          }
                          
                          pablolitoP Offline
                          pablolitoP Offline
                          pablolito
                          wrote on last edited by
                          #12

                          @raven-worx
                          Thanks a lot !

                          This does exactly what I want !

                          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