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. Multiple QComboboxes, best practice
Forum Updated to NodeBB v4.3 + New Features

Multiple QComboboxes, best practice

Scheduled Pinned Locked Moved General and Desktop
16 Posts 5 Posters 8.4k Views 1 Watching
  • 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.
  • X Offline
    X Offline
    xiit
    wrote on last edited by
    #1

    Hey!

    I have two QComboboxes, one which should display categories and another one which should change and display subcategories depending on what category you choose.

    What would be the best way to approach this?

    Here is an example:

    @Main Category 1

    • Subcat 1
    • Subcat 2
    • Some random data, like "id", "type" or w/e
      Main Category 2
    • Subcat 1
    • Some random data, like "id", "type" or w/e
    • Subcat 2@

    The main categories should be shown in the first combobox. When selecting one, its subcategories should appear in the second one. And then I should be able to access the "data" for that subcategory.

    I hope I'm clear enough about what I want to accomplish.

    Thankful for any ideas!

    1 Reply Last reply
    0
    • H Offline
      H Offline
      holygirl
      wrote on last edited by
      #2

      I'm not sure if I understood the question correctly. If you are just looking for a way to do what you are trying to do, then follow the instructions down below. If you are looking for a better or a more efficient way, then my answer may not be the right one.

      @
      QComboBox *items = new QComboBox();
      items->addItem("Item1");
      items->addItem("Item2");
      //How many ever items you want to add to the comboBox

      //This slot is to check if the text in comboBox has changed
      connect(items,SIGNAL(currentTextChanged(QString)),SLOT(display_other_items));

      //The SLOT
      void MainWindow::display_other_items()
      {
      QComboBox *subItems = new QComboBox();
      if(items->currentText=="Item1")
      {
      subItems->addItem("SubItem1");
      subItems->addItem("SubItem2");
      subItems->addItem("SubItem3");
      }
      else
      if(items->currentText=="Item2")
      {
      subItems->addItem("SubItem1");
      subItems->addItem("SubItem2");
      subItems->addItem("SubItem3");
      }
      }
      @

      1 Reply Last reply
      0
      • A Offline
        A Offline
        Adrien Leravat
        wrote on last edited by
        #3

        One possible solution would be to use a single model to represent your data, and use the QComboBox'es as view for your data. You can set the model of a QComboBox with QComboBox::setModel.

        A model can be build as a tree, thus representing the parenting of your data. Here details about "Qt Model/View models":http://doc.qt.digia.com/qt/model-view-programming.html#model-classes. Depending on what you use, you'll have to manually add data to your model, or not (Qt SQL table models for instance do that by their own. You can choose from QSqlRelationalTableModel, QStandardItemModel, etc., or your custom model based on QAbstractItemModel).

        Bind a slot to the signal QComboBox::currentIndexChanged ( int index ) of each QComboBox, and in the slot retrieve the corresponding element of your model (identified with a QModelIndex), and pass it to the next level combobox with the method
        @
        QComboBox::setRootModelIndex ( const QModelIndex & index )
        @

        You'll also have to update other child comboboxes the same way.

        This is not the easiest way to do what you want, but surely the most flexible, scalable to your data. If you look for a solid design, I'd recommand this. Else simply use QStringLists to store/retrieve your data when selection changes.

        Edit: holygirl proposal is perfect if you have few/static data.

        Adeneo Embedded - www.adeneo-embedded.com

        1 Reply Last reply
        0
        • X Offline
          X Offline
          xiit
          wrote on last edited by
          #4

          I was actually thinking of models, but it seemed a little bit too complicated for this.

          I will look in to both of your suggestions and see which suits me the most. Thanks a bunch! :)

          1 Reply Last reply
          0
          • Q Offline
            Q Offline
            qxoz
            wrote on last edited by
            #5

            Models are more prefered.
            Another variant is using QSortFilterProxyModel , and at QComboBox::currentIndexChanged ( int index ) set the filter for proxy model.

            1 Reply Last reply
            0
            • X Offline
              X Offline
              xiit
              wrote on last edited by
              #6

              Alright, I'm pretty much lost when it comes to models. I hate to ask for this, but does someone have a simple example on how to do this?

              I've googled and found various examples but they really doesn't make any sense to me. I'm probably just to stupid for this. :P

              1 Reply Last reply
              0
              • A Offline
                A Offline
                andre
                wrote on last edited by
                #7

                From a user experience perspective, I'd like to raise another issue. Are you sure that using two QComboBoxes to select a main & sub category is really the optimal solution? Personally, I don't like it much to be honest. You don't get a great overview over what is available, and you need quite a number of mouse clicks to select anything.

                Would it not make sense to use a single tree view instead, in which you allow filtering? That would allow your user to view all available categories and subcategories in one go and allow you to extend your hierarchy in places where that is needed. You could even, with some tricks, use that tree view as the dropdown-part of a QComboBox in case you lack the space for a full tree view in your form.

                The filtering feature would need a bit of work to get right. A standard QSFPM doesn't cut it, as you would have to still return main categories that have sub categories that match, even if they themselves do not match the filter (and vise versa). However, there are already topics discussing this here on the forum, complete with example code on how you could do this.

                1 Reply Last reply
                0
                • X Offline
                  X Offline
                  xiit
                  wrote on last edited by
                  #8

                  Andre: You're right. However, I want to keep the form minimalistic.

                  Say, a push button which pops up a menu when triggered and then changes text to represent what category you have chosen. Would that be considered user friendly/practical or just messy?

                  You'd have somewhat better overview than with two comboboxes though.

                  Tree view as the dropdown part of a combobox seems a little bit too advanced for me. :)

                  Thanks for your input!

                  1 Reply Last reply
                  0
                  • H Offline
                    H Offline
                    holygirl
                    wrote on last edited by
                    #9

                    I hope the following code will help. I've included comments to help you understand. I'm new to Qt myself so if my example is wrong, others will definitely point it out. Good luck!

                    @
                    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); // The DB being used
                    db.setDatabaseName("Path\test1.db"); //Where the DB lies
                    db.open(); //to open the database

                    QSqlTableModel m = new QSqlTableModel(); //Model which maps the DB to the comboBox
                    m->setTable("table"); //The table in the DB which has to be mapped
                    m->select(); //The model needs to be selected in order to use it

                    QComboBox *comboBox = new QCombobox();
                    comboBox->setModel(m); //This is where the mapping happens
                    comboBox->show();
                    @

                    1 Reply Last reply
                    0
                    • A Offline
                      A Offline
                      andre
                      wrote on last edited by
                      #10

                      The code shown by holygirl is not very useful for the case at hand. The discussion was about a set of two comboboxes with a catagory and a sub category. There was no mention of the data being stored in a data base though. The code also fails to handle the case where the thing to be displayed in the combo box is not in the first column of the table, as would often be the case (the ID is usually first).

                      1 Reply Last reply
                      0
                      • H Offline
                        H Offline
                        holygirl
                        wrote on last edited by
                        #11

                        [quote author="Andre" date="1359455436"]The code also fails to handle the case where the thing to be displayed in the combo box is not in the first column of the table, as would often be the case (the ID is usually first). [/quote]

                        Suppose we had to display the 3rd column in the comboBox, could we not do something like?
                        @
                        model->removeColumns(0,2);
                        @

                        1 Reply Last reply
                        0
                        • Q Offline
                          Q Offline
                          qxoz
                          wrote on last edited by
                          #12

                          For displaying correct column you not need delete others, just set the model column for combo box:
                          @comboBox->setModelColumn(2);//for 3rd column@

                          but still, we stepped back from the main topic.

                          1 Reply Last reply
                          0
                          • H Offline
                            H Offline
                            holygirl
                            wrote on last edited by
                            #13

                            qxoz!

                              Omg!! I didn't know I could do something like 
                            

                            @
                            comboBox->setModelColumn(int);
                            @

                            I've been deleting columns all this while to get to the correct column. Thank you SO SO much for teaching me this. I'm clearly not doing a good job learning by myself. So, thanks!

                            And sorry to the OP for deviating from the main topic.

                            1 Reply Last reply
                            0
                            • Q Offline
                              Q Offline
                              qxoz
                              wrote on last edited by
                              #14

                              You’re welcome ! :)
                              All programmers became good, by self training. Just move on.

                              1 Reply Last reply
                              0
                              • A Offline
                                A Offline
                                andre
                                wrote on last edited by
                                #15

                                Indeed. I bet, if you dig deep enough in the (public!) archives on the interwebs, you'll be able to discover many quite basic Qt and C++ questions asked by yours truly...

                                1 Reply Last reply
                                0
                                • X Offline
                                  X Offline
                                  xiit
                                  wrote on last edited by
                                  #16

                                  Okay, I think I'm starting to understand models a little bit now - though I haven't made a custom one yet. This is what I've come up with now:

                                  In my main window constructor
                                  @ QStandardItem *categoryOne = new QStandardItem("One");
                                  categoryOne->appendRow(new QStandardItem("Some"));
                                  categoryOne->appendRow(new QStandardItem("stuff"));
                                  categoryOne->appendRow(new QStandardItem("here"));

                                  QStandardItem *categoryTwo = new QStandardItem("Two");
                                  categoryTwo->appendRow(new QStandardItem("More"));
                                  categoryTwo->appendRow(new QStandardItem("stuff"));
                                  
                                  QStandardItemModel *model = new QStandardItemModel();
                                  model->appendRow(categoryOne);
                                  model->appendRow(categoryTwo);
                                  
                                  ui->comboCategory->setModel(model);
                                  ui->comboSubcategory->setModel(model);@
                                  

                                  In the currentIndexChanged slot for the main category combobox

                                  @ //QStandardItemModel model = static_cast<QStandardItemModel>(ui->comboCategory->model());

                                  QAbstractItemModel *model = ui->comboCategory->model();
                                  
                                  ui->comboSubcategory->setRootModelIndex(model->index(index, 0));
                                  ui->comboSubcategory->setCurrentIndex(0);@
                                  

                                  It seems to work fine, but is this the "correct" way of doing it?

                                  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