Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
qtws26_logo

The Qt Event of the Year: Qt World Summit 2026

Save Your Spot >
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. I'm still struggling with model/view
Qt 6.12 LTS is out! See what's new in the release blog

I'm still struggling with model/view

Scheduled Pinned Locked Moved Solved General and Desktop
27 Posts 3 Posters 10.7k Views 2 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.
  • mzimmersM mzimmers

    My final UI will have two parts: the summary table which I've described above, and a details area. The user will select a row from the table, and this will populate the details area (with more information than just the three strings). (SGaist suggested the books example, which I like and want to emulate.) So, yes, the structure array must be updated from time to time.

    mrjjM Offline
    mrjjM Offline
    mrjj
    Lifetime Qt Champion
    wrote on last edited by mrjj
    #6

    @mzimmers
    Ok. well the Address Book Example uses an QAbstractTableModel
    subclass that handles the data
    the real data lives in QList<Contact> contacts;
    Which is similar to your DeviceDetails
    so it should lead you on the right track.
    You can reuse most of the code as is, and only change the function accessing
    Contact to use your DeviceDetails instead. Rest is the same.

    1 Reply Last reply
    1
    • mzimmersM Offline
      mzimmersM Offline
      mzimmers
      wrote on last edited by
      #7

      So, in your opinion, I should go ahead and use QAbstractTableModel instead of QStandardItemModel?

      mrjjM 1 Reply Last reply
      0
      • mzimmersM mzimmers

        So, in your opinion, I should go ahead and use QAbstractTableModel instead of QStandardItemModel?

        mrjjM Offline
        mrjjM Offline
        mrjj
        Lifetime Qt Champion
        wrote on last edited by
        #8

        @mzimmers
        well the sample uses it, so it would be natural when you need full editing also.
        Also since most of the code will be 100% the same , except other data structure.

        However, if you were suggested to use QStandardItemModel, there must been a reason for that.
        Maybe to cut down on the details one must handle.
        Since DeviceDetails is flat, using a QStandardItemModel is less code and would work just as fine.

        But im not sure how the write back would e made. Were you suggested to use QStandardItemModel directly
        or to subclass it ?

        1 Reply Last reply
        1
        • mzimmersM Offline
          mzimmersM Offline
          mzimmers
          wrote on last edited by
          #9

          To make sure I'm not misquoting anyone, here's where it was first suggested:

          https://forum.qt.io/topic/90985/use-of-model-view-programming/23

          I don't really care too strongly which way I go, as long as it works and is maintainable. I don't even need to use the struct I mentioned above; I can store the data elsewhere if it simplifies the programming.

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

            Hi
            ah, QStandardItemModel was suggested over QAbstractTableModel
            since its more complex to handle. (as you might have noticed)
            with QStandardItemModel , you just give it items and overall its
            less involving than QAbstractTableModel where you will have to juggle ModelIndex() and
            call begin/end at right times etc.

            However, it does sounds like your requirements are very close to Address Book Example
            so you could reuse its model from there with very little change.
            Also, it already filters i same way as you will need.
            User click Contact, details are shown.
            User click Device, details are shown.

            But it sounded like you already copied the example and its not working 100% for you ?

            1 Reply Last reply
            1
            • mzimmersM Offline
              mzimmersM Offline
              mzimmers
              wrote on last edited by mzimmers
              #11

              No, I didn't copy the example yet...I actually started this application before being introduced to model/view. I'm now trying to retrofit whatever makes the most sense.

              In looking at the books example, I'm struck by the automation that the classes provide. I don't think there's a single instance of a "connect" command in the source code, for example. This is impressive, but it's also hard to use as an example. I'm reading the (long) page on Qt model/view and hope that will help out a bit.

              Edit: correction: there is indeed one connect. Still pretty impressive.

              mrjjM 1 Reply Last reply
              0
              • mzimmersM mzimmers

                No, I didn't copy the example yet...I actually started this application before being introduced to model/view. I'm now trying to retrofit whatever makes the most sense.

                In looking at the books example, I'm struck by the automation that the classes provide. I don't think there's a single instance of a "connect" command in the source code, for example. This is impressive, but it's also hard to use as an example. I'm reading the (long) page on Qt model/view and hope that will help out a bit.

                Edit: correction: there is indeed one connect. Still pretty impressive.

                mrjjM Offline
                mrjjM Offline
                mrjj
                Lifetime Qt Champion
                wrote on last edited by
                #12

                @mzimmers
                Well the tablemodel class handles most of that internally and the views already automatically connect to
                the signals they need from model.
                You should be able to directly use tablemodel.cpp/.h and
                only replace Contact with your struct and fix the places where its members are used.
                Then it should be working with no extra code.

                Its a good idea to read the docs on this topic. Model & Views are a bit involved but
                also provides many benefits.

                1 Reply Last reply
                0
                • VRoninV Offline
                  VRoninV Offline
                  VRonin
                  wrote on last edited by
                  #13

                  Subclassing models is a minefield. That's why I suggested using QStandardItemModel instead. The idea was that you can store

                  struct DeviceDetails
                  {
                      QString macAddr;
                      QString devName;
                      QString latestTimestamp;
                  };
                  

                  as:

                  enum DeviceRoles{
                  macAddr = Qt::UserRole
                  , devName
                  , latestTimestamp
                  };
                  auto item = new QStandardItem;
                  item->setData(/*...*/,DeviceRoles::macAddr);
                  item->setData(/*...*/,DeviceRoles::devName);
                  item->setData(/*...*/,DeviceRoles::latestTimestamp);
                  myModel.appendRow(item);
                  

                  The model subclass is probably the most correct way but before embarking into it, please read the chapter of Advanced Qt programming I linked in the previous thread and run your custom model through the Model Test

                  P.S.
                  Allocating QStandardItem on the stack is problematic. QStandardItemModel will take ownership of the item and try to delete it. That means that if you declare the item before the model

                  QStandardItem myItem;
                  QStandardItemModel myModel;
                  

                  You'll get a crash as well as if you try to remove that row you'll get a crash

                  "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                  ~Napoleon Bonaparte

                  On a crusade to banish setIndexWidget() from the holy land of Qt

                  mzimmersM 1 Reply Last reply
                  4
                  • VRoninV VRonin

                    Subclassing models is a minefield. That's why I suggested using QStandardItemModel instead. The idea was that you can store

                    struct DeviceDetails
                    {
                        QString macAddr;
                        QString devName;
                        QString latestTimestamp;
                    };
                    

                    as:

                    enum DeviceRoles{
                    macAddr = Qt::UserRole
                    , devName
                    , latestTimestamp
                    };
                    auto item = new QStandardItem;
                    item->setData(/*...*/,DeviceRoles::macAddr);
                    item->setData(/*...*/,DeviceRoles::devName);
                    item->setData(/*...*/,DeviceRoles::latestTimestamp);
                    myModel.appendRow(item);
                    

                    The model subclass is probably the most correct way but before embarking into it, please read the chapter of Advanced Qt programming I linked in the previous thread and run your custom model through the Model Test

                    P.S.
                    Allocating QStandardItem on the stack is problematic. QStandardItemModel will take ownership of the item and try to delete it. That means that if you declare the item before the model

                    QStandardItem myItem;
                    QStandardItemModel myModel;
                    

                    You'll get a crash as well as if you try to remove that row you'll get a crash

                    mzimmersM Offline
                    mzimmersM Offline
                    mzimmers
                    wrote on last edited by
                    #14

                    @VRonin OK, that makes a lot more sense. So, is the missing field in your setData() examples a pointer to my structure element? Is that how the model keeps track of changes to that data?

                    VRoninV 1 Reply Last reply
                    0
                    • mzimmersM mzimmers

                      @VRonin OK, that makes a lot more sense. So, is the missing field in your setData() examples a pointer to my structure element? Is that how the model keeps track of changes to that data?

                      VRoninV Offline
                      VRoninV Offline
                      VRonin
                      wrote on last edited by
                      #15

                      No, my example was using QStandardItemModel. the missing argument is the actual value you want to save in the model, something like item->setData(QStringLiteral("00:A0:C9:14:C8:29"),DeviceRoles::macAddr);

                      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                      ~Napoleon Bonaparte

                      On a crusade to banish setIndexWidget() from the holy land of Qt

                      1 Reply Last reply
                      1
                      • mzimmersM Offline
                        mzimmersM Offline
                        mzimmers
                        wrote on last edited by
                        #16

                        Oh, I see. So, am I then responsible for manually updating the item when data changes?

                        VRoninV 1 Reply Last reply
                        0
                        • mzimmersM mzimmers

                          Oh, I see. So, am I then responsible for manually updating the item when data changes?

                          VRoninV Offline
                          VRoninV Offline
                          VRonin
                          wrote on last edited by VRonin
                          #17

                          @mzimmers said in I'm still struggling with model/view:

                          am I then responsible for manually updating the item when data changes?

                          Correct, but that would always be the case. if you subclass QAbstractItemModel it's your responsibility to signal changes of data emitting the dataChanged signal

                          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                          ~Napoleon Bonaparte

                          On a crusade to banish setIndexWidget() from the holy land of Qt

                          1 Reply Last reply
                          1
                          • mzimmersM Offline
                            mzimmersM Offline
                            mzimmers
                            wrote on last edited by
                            #18

                            So, if I understand this, the general program flow would be:

                            1. the worker thread receives updates from the various devices
                            2. the worker passes the updates (via a signal) to the model
                            3. the model then either adds rows or modifies existing rows
                            4. the UI automatically reflects the change to the model.

                            That about right?

                            One thing I'm still not clear on, is how to modify data in existing rows, for example, changing the timestamp on a device that's already been added.

                            VRoninV 1 Reply Last reply
                            0
                            • mzimmersM mzimmers

                              So, if I understand this, the general program flow would be:

                              1. the worker thread receives updates from the various devices
                              2. the worker passes the updates (via a signal) to the model
                              3. the model then either adds rows or modifies existing rows
                              4. the UI automatically reflects the change to the model.

                              That about right?

                              One thing I'm still not clear on, is how to modify data in existing rows, for example, changing the timestamp on a device that's already been added.

                              VRoninV Offline
                              VRoninV Offline
                              VRonin
                              wrote on last edited by
                              #19

                              @mzimmers said in I'm still struggling with model/view:

                              That about right?

                              What workflow did you decide to adopt?

                              • Use QStandardItemModel
                              • or subclass QAbstractItemModel

                              "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                              ~Napoleon Bonaparte

                              On a crusade to banish setIndexWidget() from the holy land of Qt

                              1 Reply Last reply
                              1
                              • mzimmersM Offline
                                mzimmersM Offline
                                mzimmers
                                wrote on last edited by
                                #20

                                I'm now trying to use QStandardItemModel. Unfortunately, the data isn't showing up in the QTableView yet, so I'll have to work through to see where it's failing.

                                1 Reply Last reply
                                0
                                • VRoninV Offline
                                  VRoninV Offline
                                  VRonin
                                  wrote on last edited by VRonin
                                  #21

                                  I'm now trying to use QStandardItemModel

                                  Then:

                                  1. the worker thread receives updates from the various devices
                                  2. the worker passes the updates (via a signal) to a QObject in the main thread that owns the model
                                  3. the object inserts/removes/updates the model
                                  4. the UI automatically reflects the change to the model.

                                  "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                                  ~Napoleon Bonaparte

                                  On a crusade to banish setIndexWidget() from the holy land of Qt

                                  1 Reply Last reply
                                  0
                                  • mzimmersM Offline
                                    mzimmersM Offline
                                    mzimmers
                                    wrote on last edited by
                                    #22

                                    Yes, that's how I'm doing it. (My model class is DeviceModel.) Just as a test, I put this into the c'tor:

                                    DeviceModel::DeviceModel()
                                    {
                                        QString s1 = "aaa", s2 = "bbb", s3 = "ccc";
                                        QVariant qv;
                                    
                                        qv = s1;
                                        item.setData(qv, DeviceRoles::macAddr);
                                        qv = s2;
                                        item.setData(qv, DeviceRoles::devName);
                                        qv = s3;
                                        item.setData(qv, DeviceRoles::latestTimestamp);
                                        appendRow(&item);
                                    }
                                    
                                    I'd expect to see this in my QTableView, but I don't. What might I be missing?
                                    
                                    VRoninV 1 Reply Last reply
                                    0
                                    • mzimmersM mzimmers

                                      Yes, that's how I'm doing it. (My model class is DeviceModel.) Just as a test, I put this into the c'tor:

                                      DeviceModel::DeviceModel()
                                      {
                                          QString s1 = "aaa", s2 = "bbb", s3 = "ccc";
                                          QVariant qv;
                                      
                                          qv = s1;
                                          item.setData(qv, DeviceRoles::macAddr);
                                          qv = s2;
                                          item.setData(qv, DeviceRoles::devName);
                                          qv = s3;
                                          item.setData(qv, DeviceRoles::latestTimestamp);
                                          appendRow(&item);
                                      }
                                      
                                      I'd expect to see this in my QTableView, but I don't. What might I be missing?
                                      
                                      VRoninV Offline
                                      VRoninV Offline
                                      VRonin
                                      wrote on last edited by
                                      #23

                                      I'm now trying to use QStandardItemModel

                                      My model class is DeviceModel

                                      Your model class should be QStandardItemModel. Are you subclassing the model?

                                      P.S.

                                      item.

                                      as mentioned previously, you should avoid the allocation of QStandardItems on the stack as the model is supposed to own them

                                      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                                      ~Napoleon Bonaparte

                                      On a crusade to banish setIndexWidget() from the holy land of Qt

                                      1 Reply Last reply
                                      1
                                      • mzimmersM Offline
                                        mzimmersM Offline
                                        mzimmers
                                        wrote on last edited by mzimmers
                                        #24

                                        Yes:

                                        class DeviceModel : public QStandardItemModel
                                        {
                                        private:
                                            ModelData deviceTable;
                                            QStandardItem item;
                                        ...
                                        

                                        EDIT:

                                        Ohhhhhh...okay.

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

                                          so it would be like

                                          DeviceModel::DeviceModel()
                                          {
                                              QString s1 = "aaa", s2 = "bbb", s3 = "ccc";
                                              QVariant qv;
                                               QStandardItem * item = new   QStandardItem (); // model will clean up
                                              qv = s1;
                                              item->setData(qv, DeviceRoles::macAddr);
                                              qv = s2;
                                              item->setData(qv, DeviceRoles::devName);
                                              qv = s3;
                                              item->setData(qv, DeviceRoles::latestTimestamp);
                                              appendRow(item); 
                                          }
                                          
                                          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
                                          • Unsolved