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. [SOLVED] [QComboBox and Model/View] Associate PK and data in ComboBox
Qt 6.11 is out! See what's new in the release blog

[SOLVED] [QComboBox and Model/View] Associate PK and data in ComboBox

Scheduled Pinned Locked Moved General and Desktop
23 Posts 3 Posters 26.3k 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.
  • V Offline
    V Offline
    valandil211
    wrote on last edited by
    #1

    Hello Qt devs!

    This is a question related to my other post, found here. I now can show data in a categoryComboBox that depends on what is in groupComboBox. However, in the implementation, I have to add a +1. Let me show you:

    @ // Populate the group ComboBox
    groupModel = new QSqlRelationalTableModel(this, QSqlDatabase::database("*****"));
    groupModel->setTable(""TB_Groupe"");
    groupModel->setSort(groupModel->fieldIndex("GR_Nom"), Qt::AscendingOrder);
    groupModel->select();

    ui->MW_groupComboBox->setModel(groupModel);
    ui->MW_groupComboBox->setModelColumn(groupModel->fieldIndex("GR_Nom")); 
    

    // Populate category ComboBox according to Group ComboBox
    catModel = new QSqlRelationalTableModel(this, QSqlDatabase::database("*****"));
    catModel->setTable(""TB_Categorie"");
    catModel->setFilter(""CAT_IndexGroupe" = " % QString::number(ui->MW_groupComboBox->currentIndex()+1));
    catModel->setSort(catModel->fieldIndex("CAT_Nom"), Qt::AscendingOrder);
    catModel->select();

    ui->MW_catComboBox->setModel(catModel);
    ui->MW_catComboBox->setModelColumn(catModel->fieldIndex("CAT_Nom"));
    
    // Connects GroupComboBox and catComboBox to display appropriate categories
    connect(ui->MW_groupComboBox, SIGNAL(currentIndexChanged(int)),this, SLOT(RefreshCategory(int)));
    

    }

    /*********************************************
    Refreshes items in catComboBox according
    to what is in groupComboBox
    ********************************************/

    void MainWindow::RefreshCategory(int choice)
    {
    catModel->setFilter(""CAT_IndexGroupe" = " % QString::number(choice+1));
    catModel->select();

    ui->MW_catComboBox->setModel(catModel);
    ui->MW_catComboBox->setModelColumn(catModel->fieldIndex("CAT_Nom"));@
    

    Is there a way, in the backend, to associate the index of the groupComboBox to its PK in the DB? Thanks in advance! The choice+1 is an ugly, ad-hoc solution.

    Joey Dumont

    1 Reply Last reply
    0
    • L Offline
      L Offline
      loladiro
      wrote on last edited by
      #2

      No problem
      @
      groupModel->data(groupModel->index(choice, groupModel->fieldIndex("YOUR_PK_FIELD")));
      @

      1 Reply Last reply
      0
      • V Offline
        V Offline
        valandil211
        wrote on last edited by
        #3

        Unfortunately, this does not work. The variable choice is defined only in the function RefreshCategory(int). I tried it, and I still need the choice+1 so that the data displays correctly.

        Is there a way to do this during the initialization of MW_groupComboBox? I mean, I thought it would automatic, since it is another column in the same model.

        Joey Dumont

        1 Reply Last reply
        0
        • G Offline
          G Offline
          goetz
          wrote on last edited by
          #4

          "QComboBox::currentIndex() ":http://doc.qt.nokia.com/4.7/qcombobox.html#currentIndex-prop should give you the row, fieldIndex the column. With those, you can create a QModelIndex and retrieve the data.

          The code should look someting like this:

          @
          int row = comboBox->currentIndex();
          int col = groupModel->fieldIndex("YOUR_PK_FIELD");
          QModelIndex index = groupModel->index(row, col);
          QVariant PKvalue = groupModel->data(index);
          @

          http://www.catb.org/~esr/faqs/smart-questions.html

          1 Reply Last reply
          0
          • V Offline
            V Offline
            valandil211
            wrote on last edited by
            #5

            Okay. With the created QModelIndex, could I use setRootModelIndex(QModelIndex) to set the index of the ComboBox arbitrarily?

            If I understood your code, it simply maps the ComboBox index to the PKs in the appropriate DB table?

            In short, with setRootModelIndex, I should be able to replicate something like this in my ComboBox

            @ Index Data
            20 Ent
            21 Rad
            22 CQq
            @

            if I have something like that in my DB, right?

            Joey Dumont

            1 Reply Last reply
            0
            • G Offline
              G Offline
              goetz
              wrote on last edited by
              #6

              An abstract item model can contain an tree of arbitrary level. setRootModelIndex just tells the list view in the combox which of the possible subtrees it should use, it is relevant for your actual problem for getting the right index (you must set the root index as third parameter for the groupModel->index() call).

              http://www.catb.org/~esr/faqs/smart-questions.html

              1 Reply Last reply
              0
              • V Offline
                V Offline
                valandil211
                wrote on last edited by
                #7

                This still doesn't work. I thought this was supposed to be easy.

                All I want is that the values

                @MW_groupComboBox->currentIndex();@

                reflect the PKs of the data in the DB. I have tried this:

                @ QModelIndex index = groupModel->createIndex(ui->MW_groupComboBox->currentIndex(),
                groupModel->fieldIndex("IndexGroupe"));

                ui->MW_groupComboBox->setRootModelIndex(index);@
                

                which doesn't work because ::createIndex(int, int, void *ptr =0) is protected.

                Volker, I have also tried your solution, but it does nothing. @MW_groupComboBox->currentIndex();@ still returns 0 through 2, when I want it to return 1 through 3 (well, that's in the DB, I don't want to specify this literally in the code).

                I feel like this shouldn't be so complicated...

                Joey Dumont

                1 Reply Last reply
                0
                • L Offline
                  L Offline
                  loladiro
                  wrote on last edited by
                  #8

                  Use
                  @
                  QModelIndex index = groupModel->index(ui->MW_groupComboBox->currentIndex(),
                  groupModel->fieldIndex("IndexGroupe"));

                  ui->MW_groupComboBox->setRootModelIndex(index);
                  @

                  1 Reply Last reply
                  0
                  • G Offline
                    G Offline
                    goetz
                    wrote on last edited by
                    #9

                    The combo box index is set internally. You cannot set it externally to an arbitrary value.

                    If you populate the combo box with "QComboBox::addItem () ":http://doc.qt.nokia.com/4.7/qcombobox.html#addItem, you can add an arbitrary value as a "data role" for the respective item. You will have to iterate through your values manually then, you can not just set a model for the view.

                    http://www.catb.org/~esr/faqs/smart-questions.html

                    1 Reply Last reply
                    0
                    • V Offline
                      V Offline
                      valandil211
                      wrote on last edited by
                      #10

                      Tried this. Now my ComboBox has only a single item. Can't I designate a column of my model to be the index of the ComboBox, or something similar?

                      Joey Dumont

                      1 Reply Last reply
                      0
                      • G Offline
                        G Offline
                        goetz
                        wrote on last edited by
                        #11

                        [quote author="Joey Dumont" date="1309265662"]Tried this. Now my ComboBox has only a single item. Can't I designate a column of my model to be the index of the ComboBox, or something similar?[/quote]

                        NO

                        http://www.catb.org/~esr/faqs/smart-questions.html

                        1 Reply Last reply
                        0
                        • L Offline
                          L Offline
                          loladiro
                          wrote on last edited by
                          #12

                          [quote author="Joey Dumont" date="1309265662"]Tried this. Now my ComboBox has only a single item. Can't I designate a column of my model to be the index of the ComboBox, or something similar?[/quote]

                          You can always do what Volker suggested above (That accesses another column with the current index). If you think that's too much code everytime you want to access the index, I'm afraid you'll have to subclass QComboBox

                          [quote]
                          @
                          int row = comboBox->currentIndex();
                          int col = groupModel->fieldIndex("YOUR_PK_FIELD");
                          QModelIndex index = groupModel->index(row, col);
                          QVariant PKvalue = groupModel->data(index);
                          @
                          [/quote]

                          1 Reply Last reply
                          0
                          • G Offline
                            G Offline
                            goetz
                            wrote on last edited by
                            #13

                            [quote author="loladiro" date="1309266013"]
                            You can always do what Volker suggested above (That accesses another column with the current index). If you think that's too much code everytime you want to access the index, I'm afraid you'll have to subclass QComboBox
                            [/quote]

                            That would just move that code into the subclass...

                            http://www.catb.org/~esr/faqs/smart-questions.html

                            1 Reply Last reply
                            0
                            • L Offline
                              L Offline
                              loladiro
                              wrote on last edited by
                              #14

                              Very true, I only suggested it, because he didn't seem to want to go through the entire process every time he access the index.

                              1 Reply Last reply
                              0
                              • V Offline
                                V Offline
                                valandil211
                                wrote on last edited by
                                #15

                                Thanks, Volker. Now, that brings another question. I'm using something like that to fetch data from a DB.
                                !https://lh6.googleusercontent.com/-Eyg_apku1S8/TgnRSDAAVnI/AAAAAAAAB34/YKLXdQehE84/s800/Screenshot-Contr%25C3%25B4les%2520de%2520qualit%25C3%25A9-1.jpg!

                                The Category CC changes according to the Index of the GroupCC, as said earlier. Now, since I cannot set the Index of the ComboBox, the complexity of the query seems to increase rapidly (I need to account for the index of the group when binding a value to the category, etc...)

                                By subclassing QComboBox, could I set the index myself, or is this really impossible? Thanks!

                                Joey Dumont

                                1 Reply Last reply
                                0
                                • G Offline
                                  G Offline
                                  goetz
                                  wrote on last edited by
                                  #16

                                  You get a signal when the group combo box changes. Get the data out of the group combo box' model (you have at least two choices pointed out here in the thread) and fill the model for the category's model accordingly. You'll have to re-select from the SQL anyways or put all the data in cache or the like which you access with the selected group's data.

                                  http://www.catb.org/~esr/faqs/smart-questions.html

                                  1 Reply Last reply
                                  0
                                  • V Offline
                                    V Offline
                                    valandil211
                                    wrote on last edited by
                                    #17

                                    Oh, the category CC already changes according to the index of the group CC (see the code I first posted).

                                    However, the five ComboBox uniquely identifies a set of data in the DB. Hence, I thought that if I could change the index of the ComboBox that I could directly use

                                    @query.prepare("...WHERE IndexAcc = :acc");
                                    query.bindValue(":acc", accComboBox->currentIndex();@

                                    because I thought that using something like

                                    @
                                    query.prepare("...WHERE name_acc = :acc");
                                    query.bindValue(":acc", accComboBox->currentText().toString());@

                                    was error-prone. Ain't it?

                                    Joey Dumont

                                    1 Reply Last reply
                                    0
                                    • V Offline
                                      V Offline
                                      valandil211
                                      wrote on last edited by
                                      #18

                                      [quote author="loladiro" date="1309266013"]
                                      You can always do what Volker suggested above (That accesses another column with the current index). If you think that's too much code everytime you want to access the index, I'm afraid you'll have to subclass QComboBox
                                      [/quote]

                                      Okay, now I understand this part better. However, what I need is relational table, because for one value of the GroupComboBox index, I have several possible values for the Category ComboBox index.

                                      Joey Dumont

                                      1 Reply Last reply
                                      0
                                      • G Offline
                                        G Offline
                                        goetz
                                        wrote on last edited by
                                        #19

                                        A primary key is a primary key - a string value need not be unique.

                                        So you're doing it the wrong way anyways.

                                        query.bindValue() sets the value to the current value of that variable. It is not updated once the value changes! No matter how often you run the query, it always yields the same results!

                                        You must call bindValue again after the value has changed (i.e. after the combo box has a new current item) and re-run the query!

                                        http://www.catb.org/~esr/faqs/smart-questions.html

                                        1 Reply Last reply
                                        0
                                        • V Offline
                                          V Offline
                                          valandil211
                                          wrote on last edited by
                                          #20

                                          [quote author="Volker" date="1309267439"]A primary key is a primary key - a string value need not be unique.

                                          So you're doing it the wrong way anyways.

                                          query.bindValue() sets the value to the current value of that variable. It is not updated once the value changes! No matter how often you run the query, it always yields the same results!

                                          You must call bindValue again after the value has changed (i.e. after the combo box has a new current item) and re-run the query![/quote]

                                          Yes, I know all that. This sort of query will be connected to a button (now yet implemented) that will bind the values of whatever is in the ComboBoxes to a prepared SQL query and update the UI accordingly. However, from what you're telling me, I can access the PK associated with a certain item in the groupComboBox by using the currentIndex() of the groupComboBox and externally mapping it to its PK. That's fine.

                                          However, for each item in the groupComboBox, there are several items in the categoryComboBox. Now, since each time I change the index of groupComboBox, the contents of the categoryComboBox are changed, I cannot map the PK of the categoryComboBox to its index. Do you understand my problem?

                                          Because of this one-to-many relationship, it is somewhat difficult to implement something that would bind the right value in the SQL query. Now, and I want this to be the final question in this grudgingly long thread, can I set the indices of ComboBoxes if I subclass them?

                                          (To me, it seems like the most robust solution to fetch data from the DB.)

                                          Thanks, y'all!

                                          Joey Dumont

                                          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