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. Presetting a combobox to one of its tree view popup entry
QtWS25 Last Chance

Presetting a combobox to one of its tree view popup entry

Scheduled Pinned Locked Moved Solved General and Desktop
11 Posts 5 Posters 1.9k 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.
  • B Offline
    B Offline
    Bert59
    wrote on 1 Apr 2021, 19:56 last edited by
    #1

    Hi,
    I have a combobox with a popup treeview as shown below.
    b289155e-d0ce-4f3c-a718-c96b49586a52-image.png
    I would like to set the combobox current item programmaticaly to one of the child items.

    How can I achieve that ?

    P 1 Reply Last reply 2 Apr 2021, 00:43
    0
    • B Offline
      B Offline
      Bert59
      wrote on 2 Apr 2021, 15:07 last edited by
      #9

      Finally I found a way to make it work.
      First I have created a subclass for QCombobox called TreeBox.

      TreeBox::TreeBox(QWidget *parent) : QComboBox(parent)
      {
          m_tree = new QTreeView;
          this->setView(m_tree);
      
          m_tree->setHeaderHidden(true);
          m_tree->viewport()->installEventFilter(this);
      }
      

      Then in the class which is using the TreeBox I have declared a private property to keep track of the items added to the list view.

      QVector<QStandardItem*> m_itemList;
      QStandardItemModel m_modelForTree;
      

      In the ui I have added a ComboBox and promoted it to TreeBox.
      Then I populate the tree model as follows and set the model to the ComboBox.

      QStandardItem *root = m_modelForTree.invisibleRootItem();
          QStandardItem *item;
          for (int i=0; i<10; i++){
              item = new QStandardItem(QString("item %0").arg(i));
              m_itemList.append(item);
              root->appendRow(item);
              for(int j=0; j<5; j++){
                  item->setChild(j, 0, new QStandardItem(QString("item %0%1").arg(i).arg(j)));
              }
          }
      
          ui->comboBox->setModel(&m_modelForTree);
      

      As an example I choose "item 43" to be set at the startup of this test program.

      QString text = "item 43";
      

      Then I loop through the QStandardListItems in m_itemList to find the QModelIndex of the item I want to preset.

      bool textFound=false;
          QModelIndex modelIndex;
          for (int i=0; i<m_itemList.count(); i++){
              for (int j=0; j<m_itemList[i]->rowCount(); j++){
                  modelIndex = m_modelForTree.indexFromItem(m_itemList[i]->child(j));
                  if (modelIndex.data(Qt::DisplayRole).toString()==text){
                      textFound = true;
                      break;
                  }
              }
              if (textFound)
                  break;
          }
      

      Now I can set the item as follows

      ui->comboBox->setRootModelIndex(modelIndex.parent());
      ui->comboBox->setCurrentIndex(modelIndex.row());
      

      Unfortunately this restricts also the items displayed in the popup of the combobox to those of the current parent item.
      9807f986-bb64-4ecd-87ad-c875361c6d58-image.png

      To avoid this behavior I have to reset to the first QStandardItem in the list

          modelIndex = m_modelForTree.indexFromItem(m_itemList[0]);
          ui->comboBox->setRootModelIndex(modelIndex.parent());
      

      Now I get the behaviour I was looking for
      8e08d83e-4626-467b-9119-a6da38c7b365-image.png

      Maybe there are simpler ways to do it and I would be glad if someone could come up with one.
      But for the time being I just wanted to share this solution.

      T 1 Reply Last reply 27 Oct 2022, 15:31
      1
      • B Bert59
        1 Apr 2021, 19:56

        Hi,
        I have a combobox with a popup treeview as shown below.
        b289155e-d0ce-4f3c-a718-c96b49586a52-image.png
        I would like to set the combobox current item programmaticaly to one of the child items.

        How can I achieve that ?

        P Offline
        P Offline
        Pl45m4
        wrote on 2 Apr 2021, 00:43 last edited by
        #2

        @Bert59

        Check what index they have and then just setCurrentIndex(idx).


        If debugging is the process of removing software bugs, then programming must be the process of putting them in.

        ~E. W. Dijkstra

        1 Reply Last reply
        0
        • B Offline
          B Offline
          Bert59
          wrote on 2 Apr 2021, 07:20 last edited by
          #3

          But how do I get the index of an item? If I just now the name, for example "item 24", how can I get the index for it?

          J 1 Reply Last reply 2 Apr 2021, 07:29
          0
          • B Bert59
            2 Apr 2021, 07:20

            But how do I get the index of an item? If I just now the name, for example "item 24", how can I get the index for it?

            J Offline
            J Offline
            JonB
            wrote on 2 Apr 2021, 07:29 last edited by JonB 4 Feb 2021, 07:34
            #4

            @Bert59
            You must search the tree view items for the one matching item 24. You could try QComboBox::findText() to do that, I don't know if it works for you but worth a try.

            If you say all you want to do is set the current item, have you tried simply yourComboBox->setCurrentText("item 24")? I don't know whether that will work with a tree view, and selecting a sub-item, but again worth a try?

            B 1 Reply Last reply 2 Apr 2021, 07:38
            0
            • J JonB
              2 Apr 2021, 07:29

              @Bert59
              You must search the tree view items for the one matching item 24. You could try QComboBox::findText() to do that, I don't know if it works for you but worth a try.

              If you say all you want to do is set the current item, have you tried simply yourComboBox->setCurrentText("item 24")? I don't know whether that will work with a tree view, and selecting a sub-item, but again worth a try?

              B Offline
              B Offline
              Bert59
              wrote on 2 Apr 2021, 07:38 last edited by
              #5

              Thank you for the feedback.
              Unfortunately both methods only work for the root items (item 2 for example) but not for the child items like "item 24".

              J 1 Reply Last reply 2 Apr 2021, 07:46
              0
              • B Bert59
                2 Apr 2021, 07:38

                Thank you for the feedback.
                Unfortunately both methods only work for the root items (item 2 for example) but not for the child items like "item 24".

                J Offline
                J Offline
                JonB
                wrote on 2 Apr 2021, 07:46 last edited by JonB 4 Feb 2021, 07:49
                #6

                @Bert59
                Yes I did wonder if that might be the case.

                That only means you cannot use the two quick ...text() methods. Revert to what I said first (which is what ...text() methods would have to do internally anyway): search the tree view/model for the item you want. I assume you have tested that setCurrentIndex(7) does indeed select item 24 correctly, so you know all you have to do is correctly find that item 24 is at item #7 and it will then select correctly? (If it does not do that, and actually selects item 7 which is presumably scrolled down at the bottom, then you have a problem....)

                1 Reply Last reply
                0
                • B Offline
                  B Offline
                  Bert59
                  wrote on 2 Apr 2021, 07:56 last edited by
                  #7

                  setCurrentIndex(7) selects in fact "item 7".

                  I think I should use ui->comboBox->view()->setCurrentIndex(index);

                  But in this method index is a QModelIndex and so far I couldn't find a way to get the QModelIndex from the items name.

                  J 1 Reply Last reply 2 Apr 2021, 08:05
                  0
                  • B Bert59
                    2 Apr 2021, 07:56

                    setCurrentIndex(7) selects in fact "item 7".

                    I think I should use ui->comboBox->view()->setCurrentIndex(index);

                    But in this method index is a QModelIndex and so far I couldn't find a way to get the QModelIndex from the items name.

                    J Offline
                    J Offline
                    JonB
                    wrote on 2 Apr 2021, 08:05 last edited by JonB 4 Feb 2021, 08:05
                    #8

                    @Bert59 said in Presetting a combobox to one of its tree view popup entry:

                    setCurrentIndex(7) selects in fact "item 7".

                    Then you should stop and realise this is telling you your whole idea is flawed/does not work.

                    A QComboBox works from a single, integer index, not a QModelIndex. Your finding shows that no value for QComboBox::setCurrentIndex() is going to select a non-top-level item/node such as item 24. Rather, it only works on the top-level items, and that's all it will allow you to select/return as selected. Even if you find item 24's QModelIndex in the model, how will that help you select/return it in a combo box?

                    QCombBox only works for a "flat" list of items. Not some tree view hierarchy. Where did you get the idea from that you could make it work with a tree view? Have you found any code example anywhere which says that can be done?

                    1 Reply Last reply
                    0
                    • B Offline
                      B Offline
                      Bert59
                      wrote on 2 Apr 2021, 15:07 last edited by
                      #9

                      Finally I found a way to make it work.
                      First I have created a subclass for QCombobox called TreeBox.

                      TreeBox::TreeBox(QWidget *parent) : QComboBox(parent)
                      {
                          m_tree = new QTreeView;
                          this->setView(m_tree);
                      
                          m_tree->setHeaderHidden(true);
                          m_tree->viewport()->installEventFilter(this);
                      }
                      

                      Then in the class which is using the TreeBox I have declared a private property to keep track of the items added to the list view.

                      QVector<QStandardItem*> m_itemList;
                      QStandardItemModel m_modelForTree;
                      

                      In the ui I have added a ComboBox and promoted it to TreeBox.
                      Then I populate the tree model as follows and set the model to the ComboBox.

                      QStandardItem *root = m_modelForTree.invisibleRootItem();
                          QStandardItem *item;
                          for (int i=0; i<10; i++){
                              item = new QStandardItem(QString("item %0").arg(i));
                              m_itemList.append(item);
                              root->appendRow(item);
                              for(int j=0; j<5; j++){
                                  item->setChild(j, 0, new QStandardItem(QString("item %0%1").arg(i).arg(j)));
                              }
                          }
                      
                          ui->comboBox->setModel(&m_modelForTree);
                      

                      As an example I choose "item 43" to be set at the startup of this test program.

                      QString text = "item 43";
                      

                      Then I loop through the QStandardListItems in m_itemList to find the QModelIndex of the item I want to preset.

                      bool textFound=false;
                          QModelIndex modelIndex;
                          for (int i=0; i<m_itemList.count(); i++){
                              for (int j=0; j<m_itemList[i]->rowCount(); j++){
                                  modelIndex = m_modelForTree.indexFromItem(m_itemList[i]->child(j));
                                  if (modelIndex.data(Qt::DisplayRole).toString()==text){
                                      textFound = true;
                                      break;
                                  }
                              }
                              if (textFound)
                                  break;
                          }
                      

                      Now I can set the item as follows

                      ui->comboBox->setRootModelIndex(modelIndex.parent());
                      ui->comboBox->setCurrentIndex(modelIndex.row());
                      

                      Unfortunately this restricts also the items displayed in the popup of the combobox to those of the current parent item.
                      9807f986-bb64-4ecd-87ad-c875361c6d58-image.png

                      To avoid this behavior I have to reset to the first QStandardItem in the list

                          modelIndex = m_modelForTree.indexFromItem(m_itemList[0]);
                          ui->comboBox->setRootModelIndex(modelIndex.parent());
                      

                      Now I get the behaviour I was looking for
                      8e08d83e-4626-467b-9119-a6da38c7b365-image.png

                      Maybe there are simpler ways to do it and I would be glad if someone could come up with one.
                      But for the time being I just wanted to share this solution.

                      T 1 Reply Last reply 27 Oct 2022, 15:31
                      1
                      • B Bert59
                        2 Apr 2021, 15:07

                        Finally I found a way to make it work.
                        First I have created a subclass for QCombobox called TreeBox.

                        TreeBox::TreeBox(QWidget *parent) : QComboBox(parent)
                        {
                            m_tree = new QTreeView;
                            this->setView(m_tree);
                        
                            m_tree->setHeaderHidden(true);
                            m_tree->viewport()->installEventFilter(this);
                        }
                        

                        Then in the class which is using the TreeBox I have declared a private property to keep track of the items added to the list view.

                        QVector<QStandardItem*> m_itemList;
                        QStandardItemModel m_modelForTree;
                        

                        In the ui I have added a ComboBox and promoted it to TreeBox.
                        Then I populate the tree model as follows and set the model to the ComboBox.

                        QStandardItem *root = m_modelForTree.invisibleRootItem();
                            QStandardItem *item;
                            for (int i=0; i<10; i++){
                                item = new QStandardItem(QString("item %0").arg(i));
                                m_itemList.append(item);
                                root->appendRow(item);
                                for(int j=0; j<5; j++){
                                    item->setChild(j, 0, new QStandardItem(QString("item %0%1").arg(i).arg(j)));
                                }
                            }
                        
                            ui->comboBox->setModel(&m_modelForTree);
                        

                        As an example I choose "item 43" to be set at the startup of this test program.

                        QString text = "item 43";
                        

                        Then I loop through the QStandardListItems in m_itemList to find the QModelIndex of the item I want to preset.

                        bool textFound=false;
                            QModelIndex modelIndex;
                            for (int i=0; i<m_itemList.count(); i++){
                                for (int j=0; j<m_itemList[i]->rowCount(); j++){
                                    modelIndex = m_modelForTree.indexFromItem(m_itemList[i]->child(j));
                                    if (modelIndex.data(Qt::DisplayRole).toString()==text){
                                        textFound = true;
                                        break;
                                    }
                                }
                                if (textFound)
                                    break;
                            }
                        

                        Now I can set the item as follows

                        ui->comboBox->setRootModelIndex(modelIndex.parent());
                        ui->comboBox->setCurrentIndex(modelIndex.row());
                        

                        Unfortunately this restricts also the items displayed in the popup of the combobox to those of the current parent item.
                        9807f986-bb64-4ecd-87ad-c875361c6d58-image.png

                        To avoid this behavior I have to reset to the first QStandardItem in the list

                            modelIndex = m_modelForTree.indexFromItem(m_itemList[0]);
                            ui->comboBox->setRootModelIndex(modelIndex.parent());
                        

                        Now I get the behaviour I was looking for
                        8e08d83e-4626-467b-9119-a6da38c7b365-image.png

                        Maybe there are simpler ways to do it and I would be glad if someone could come up with one.
                        But for the time being I just wanted to share this solution.

                        T Offline
                        T Offline
                        TalonB21
                        wrote on 27 Oct 2022, 15:31 last edited by
                        #10
                        This post is deleted!
                        1 Reply Last reply
                        0
                        • G Offline
                          G Offline
                          grab7009
                          wrote on 27 Jun 2024, 15:45 last edited by
                          #11

                          I know this is old but I just wanted to thank you for posting this solution. A QComboBox will absolutely accept a tree model and it is NOT a sign of incorrect design or usage. It is strange that QComboBox will accept a model as the source but not return a model index when queried, but swapping root model indices and setting the current row index worked perfectly!

                          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