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. Custom Table Model
Forum Updated to NodeBB v4.3 + New Features

Custom Table Model

Scheduled Pinned Locked Moved Unsolved General and Desktop
28 Posts 7 Posters 3.5k Views 3 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.
  • E Offline
    E Offline
    EaccB
    wrote on last edited by EaccB
    #1

    [Simplified description of classes]

    I have a class StudentsManager which amongst other things, contains a vector of Student objects. Each student object contains an id, name, and DOB.

    In my main window, I need a read-only Table view which reflects the contents of the Student vector in StudentsManager.

    How can I bind StudentsManager to a custom table model, or should StudentsManager itself be the model? Code examples would be greatly appreciated.

    Also, when a row is selected, I need a pointer to the respective Student object.

    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by mrjj
      #2

      Hi
      You could use a TableWidget directly
      https://wiki.qt.io/How_to_Use_QTableWidget
      ( it uses a model internally but its not exactly what you ask)

      You can use an std model
      https://doc.qt.io/qt-5/qstandarditemmodel.html
      And simply use a USER role to store a pointer to the source StudentsManager
      https://doc.qt.io/qt-5/model-view-programming.html
      section Roles.

      This is ok since it's read-only as else it gets clumsy to update the items again if StudentsManager data changes.

      You can also go full-blown custom model like
      https://doc.qt.io/qt-5/qtwidgets-itemviews-addressbook-example.html

      1 Reply Last reply
      1
      • E Offline
        E Offline
        EaccB
        wrote on last edited by
        #3

        At the moment, I'm using QTableView with a custom model which holds a pointer to the students vector held in StudentManager. What do you think?

        Another problem I have:

        When I delete a student object from inside the StudentManager, how can I refresh the Table View to reflect the change in data?

        Christian EhrlicherC 1 Reply Last reply
        0
        • E EaccB

          At the moment, I'm using QTableView with a custom model which holds a pointer to the students vector held in StudentManager. What do you think?

          Another problem I have:

          When I delete a student object from inside the StudentManager, how can I refresh the Table View to reflect the change in data?

          Christian EhrlicherC Offline
          Christian EhrlicherC Offline
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @EaccB said in Custom Table Model:

          What do you think?

          That's exactly how I would implement it.

          how can I refresh the Table View to reflect the change in data?

          Your model has to emit a dataChanged() signal.

          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
          Visit the Qt Academy at https://academy.qt.io/catalog

          E 1 Reply Last reply
          3
          • Christian EhrlicherC Christian Ehrlicher

            @EaccB said in Custom Table Model:

            What do you think?

            That's exactly how I would implement it.

            how can I refresh the Table View to reflect the change in data?

            Your model has to emit a dataChanged() signal.

            E Offline
            E Offline
            EaccB
            wrote on last edited by
            #5

            @Christian-Ehrlicher said in Custom Table Model:

            That's exactly how I would implement it.

            So just to be clear, the model is effectively a wrapper around a data structure held elsewhere?

            How would I emit the dataChanged() signal? Do there need to be any parameters passed?
            Also, as I'm changing the data from within the StudentManager object, how can I let the model know the data has been updated?

            JonBJ 1 Reply Last reply
            0
            • E EaccB

              @Christian-Ehrlicher said in Custom Table Model:

              That's exactly how I would implement it.

              So just to be clear, the model is effectively a wrapper around a data structure held elsewhere?

              How would I emit the dataChanged() signal? Do there need to be any parameters passed?
              Also, as I'm changing the data from within the StudentManager object, how can I let the model know the data has been updated?

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

              @EaccB

              the model is effectively a wrapper around a data structure held elsewhere

              In this case, yes. In other cases the model holds the data structure.

              Start by reading through https://doc.qt.io/qt-5/qabstractitemmodel.html#dataChanged.

              E 1 Reply Last reply
              1
              • JonBJ JonB

                @EaccB

                the model is effectively a wrapper around a data structure held elsewhere

                In this case, yes. In other cases the model holds the data structure.

                Start by reading through https://doc.qt.io/qt-5/qabstractitemmodel.html#dataChanged.

                E Offline
                E Offline
                EaccB
                wrote on last edited by EaccB
                #7

                @JonB

                Here's what I've done, which seems to work:

                void MainWindow::on_DeleteButton_clicked()
                {
                    QItemSelectionModel *selected = ui->tableView->selectionModel();
                    QModelIndexList rowList = selected->selectedRows();
                
                
                    for (int i = 0; i < rowList.count(); i++)
                    {
                
                        ui->label->setText(students.at(rowList.at(i).row()).name);
                        students.removeAt(rowList.at(i).row());
                        StudentModel->update();
                
                    }
                }
                
                
                void StudentModel::update(){
                
                   QModelIndex i = this->index(0,0,QModelIndex());
                   QModelIndex p = this->index(0,1,QModelIndex());
                   emit dataChanged(i,p);
                }
                

                What I don't understand is what the value in index() relate to. Admittedly I chose them randomly until it worked. Also, is it ok to get the index using "this->"?

                1 Reply Last reply
                0
                • Christian EhrlicherC Offline
                  Christian EhrlicherC Offline
                  Christian Ehrlicher
                  Lifetime Qt Champion
                  wrote on last edited by Christian Ehrlicher
                  #8

                  @EaccB said in Custom Table Model:

                  What I don't understand is what the value in index() relate to

                  You should take a look here

                  Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                  Visit the Qt Academy at https://academy.qt.io/catalog

                  E 1 Reply Last reply
                  2
                  • Christian EhrlicherC Christian Ehrlicher

                    @EaccB said in Custom Table Model:

                    What I don't understand is what the value in index() relate to

                    You should take a look here

                    E Offline
                    E Offline
                    EaccB
                    wrote on last edited by
                    #9

                    @Christian-Ehrlicher

                    I see. So doing something like this would update every cell in the table?

                    QModelIndex i = this->index(0,0,QModelIndex());
                    QModelIndex p = this->index(students.size()-1,1,QModelIndex());
                    
                    1 Reply Last reply
                    0
                    • Christian EhrlicherC Offline
                      Christian EhrlicherC Offline
                      Christian Ehrlicher
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      Yes, but for this you should use begin/endResetModel() and you should only use it when you really need it. Make sure to only call dataChanged() for stuff you need.

                      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                      Visit the Qt Academy at https://academy.qt.io/catalog

                      1 Reply Last reply
                      2
                      • E Offline
                        E Offline
                        EaccB
                        wrote on last edited by
                        #11

                        So are you saying that ideally I should only emit dataChanged() on the rows affected?

                        SGaistS 1 Reply Last reply
                        0
                        • E EaccB

                          So are you saying that ideally I should only emit dataChanged() on the rows affected?

                          SGaistS Offline
                          SGaistS Offline
                          SGaist
                          Lifetime Qt Champion
                          wrote on last edited by
                          #12

                          Hi,

                          @EaccB said in Custom Table Model:

                          So are you saying that ideally I should only emit dataChanged() on the rows affected?

                          Yes, this will avoid unneeded processing and updating of the GUI for things that did not change.

                          Interested in AI ? www.idiap.ch
                          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                          E 1 Reply Last reply
                          1
                          • SGaistS SGaist

                            Hi,

                            @EaccB said in Custom Table Model:

                            So are you saying that ideally I should only emit dataChanged() on the rows affected?

                            Yes, this will avoid unneeded processing and updating of the GUI for things that did not change.

                            E Offline
                            E Offline
                            EaccB
                            wrote on last edited by EaccB
                            #13

                            @SGaist

                            Ok, here's what I've done:

                            void TestModel::update(int row){
                            
                               QModelIndex i = this->index(row,0,QModelIndex());
                               QModelIndex p = this->index(row,1,QModelIndex());
                            
                               emit dataChanged(i,p);
                            }
                            

                            This way, only the affected row is updated.

                            1 Reply Last reply
                            0
                            • SGaistS Offline
                              SGaistS Offline
                              SGaist
                              Lifetime Qt Champion
                              wrote on last edited by
                              #14

                              dataChange takes a range so here you always emit that the it starts from the first up to the row you pass as parameter. Is it really always the case ?

                              Interested in AI ? www.idiap.ch
                              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                              E 2 Replies Last reply
                              0
                              • SGaistS SGaist

                                dataChange takes a range so here you always emit that the it starts from the first up to the row you pass as parameter. Is it really always the case ?

                                E Offline
                                E Offline
                                EaccB
                                wrote on last edited by
                                #15

                                @SGaist

                                I edited my answer.

                                1 Reply Last reply
                                0
                                • SGaistS SGaist

                                  dataChange takes a range so here you always emit that the it starts from the first up to the row you pass as parameter. Is it really always the case ?

                                  E Offline
                                  E Offline
                                  EaccB
                                  wrote on last edited by
                                  #16

                                  @SGaist

                                  When emitting dataChanged(i,p) for the deleted row only, how is it that the following rows move up? Wouldn't that require a dataChanged(i,p) for the whole table?

                                  1 Reply Last reply
                                  0
                                  • Christian EhrlicherC Offline
                                    Christian EhrlicherC Offline
                                    Christian Ehrlicher
                                    Lifetime Qt Champion
                                    wrote on last edited by Christian Ehrlicher
                                    #17

                                    @EaccB said in Custom Table Model:

                                    When emitting dataChanged(i,p) for the deleted row only,

                                    You did not read my link. You must not call dataChanged() when removing a row.

                                    Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                                    Visit the Qt Academy at https://academy.qt.io/catalog

                                    E 1 Reply Last reply
                                    4
                                    • Christian EhrlicherC Christian Ehrlicher

                                      @EaccB said in Custom Table Model:

                                      When emitting dataChanged(i,p) for the deleted row only,

                                      You did not read my link. You must not call dataChanged() when removing a row.

                                      E Offline
                                      E Offline
                                      EaccB
                                      wrote on last edited by
                                      #18

                                      @Christian-Ehrlicher

                                      Then what do I use to signal to the view that the model has been updated? I've removed dataChanged() and replaced it with layoutChanged() which seems to work fine.

                                      To avoid any confusion, the table itself is read-only and should only reflect the contents of the students vector inside StudentManager. Any changes to the data (i.e. add student, edit student, remove student) are done directly on the students vector.

                                      1 Reply Last reply
                                      0
                                      • Christian EhrlicherC Offline
                                        Christian EhrlicherC Offline
                                        Christian Ehrlicher
                                        Lifetime Qt Champion
                                        wrote on last edited by
                                        #19

                                        @EaccB said in Custom Table Model:

                                        Then what do I use to signal to the view that the model has been updated?

                                        dataChanged() as explained above.

                                        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                                        Visit the Qt Academy at https://academy.qt.io/catalog

                                        E 1 Reply Last reply
                                        1
                                        • Christian EhrlicherC Christian Ehrlicher

                                          @EaccB said in Custom Table Model:

                                          Then what do I use to signal to the view that the model has been updated?

                                          dataChanged() as explained above.

                                          E Offline
                                          E Offline
                                          EaccB
                                          wrote on last edited by
                                          #20

                                          @Christian-Ehrlicher

                                          Ok, I'm really confused. You said that I shouldn't use dataChanged() when removing a row. So, what should I do when an element is removed from the vector? Or are you saying that I should emit dataChanged from the class which owns the vector and connect it to a slot in the Model?

                                          JonBJ 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