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. use of model/view programming
Forum Updated to NodeBB v4.3 + New Features

use of model/view programming

Scheduled Pinned Locked Moved Unsolved General and Desktop
27 Posts 6 Posters 4.9k 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.
  • SGaistS Offline
    SGaistS Offline
    SGaist
    Lifetime Qt Champion
    wrote on last edited by
    #16

    That's another possibility yes.

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

    1 Reply Last reply
    2
    • mzimmersM mzimmers

      OK, now we're getting somewhere. Can I simply pass in a pointer to it in the c'tor, then?

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

      @mzimmers
      Yes, if you'd like to do it there, as per @SGaist 's example.

      Is your confusion that you don't know that you can, for example, make your example Widget constructor take extra parameters beyond what the base QWidget() takes? You can pass whatever additional stuff you like to your constructor if you wish to write it like that.

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

        Thanks, guys. No, my confusion wasn't using the c'tor, it was whether manually passing a pointer to the model, into the display widget, was the right way to do this. I'm going to go implement this, and will return with my next confusion in a bit. Thanks again...

        UPDATE:

        Believe it or not, I have it working. (Still haven't implemented SGaist's design suggestion but I will.) So, I think the next thing to do is to implement my override of insertRows()/beginInsertRows().

        So, is the correct sequence in insertRows() to:

        1. call beginInsertRows() and add a row
        2. add the data to be inserted to my private copy of the data
        3. call endInsertRows()

        In other words, will the insertRows() function I write will modify my copy of the data (the model)?

        Also, beginInsertRows() has an argument const QModelIndex &parent. What is this, and where do I get it from?

        Thanks...

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

          I've used the address book example as a guide, and it's sort of working. I can successfully add a row, and populate its contents. But when I try to update a row (actually just one column in the row), the update doesn't show in the widget.

          Here's my update code...am I forgetting a window refresh or something? I don't see anything like that in the address book example.

          Thanks...

              // update the row. Easiest to just do all fields.
              deviceTable[row.Srow] = device;
              QModelIndex id = index(row.Srow, 0, QModelIndex());
              setData(id, device.macAddr, Qt::EditRole);
              id = index(row.Srow, 1, QModelIndex());
              setData(id, device.devName, Qt::EditRole);
              id = index(row.Srow, 2, QModelIndex());
              setData(id, device.latestHB, Qt::EditRole);
          
              //emit a signal to make the view re-read identified data.
              QModelIndex topLeft = createIndex(0, 0);
              row.Urow = deviceTable.size();
              QModelIndex bottomRight = createIndex(row.Srow, NBR_COLS_IN_TABLE);
              emit dataChanged(topLeft, bottomRight);
          

          Edit: it was pointed out that my row and column values were off by 1 each; I've corrected that (not reflected in the code above), and the behavior is unchanged.

          The field should update about once a second, but it updates whenever it loses or gains focus. Any suggestions are appreciated.

          kshegunovK 1 Reply Last reply
          0
          • mzimmersM mzimmers

            I've used the address book example as a guide, and it's sort of working. I can successfully add a row, and populate its contents. But when I try to update a row (actually just one column in the row), the update doesn't show in the widget.

            Here's my update code...am I forgetting a window refresh or something? I don't see anything like that in the address book example.

            Thanks...

                // update the row. Easiest to just do all fields.
                deviceTable[row.Srow] = device;
                QModelIndex id = index(row.Srow, 0, QModelIndex());
                setData(id, device.macAddr, Qt::EditRole);
                id = index(row.Srow, 1, QModelIndex());
                setData(id, device.devName, Qt::EditRole);
                id = index(row.Srow, 2, QModelIndex());
                setData(id, device.latestHB, Qt::EditRole);
            
                //emit a signal to make the view re-read identified data.
                QModelIndex topLeft = createIndex(0, 0);
                row.Urow = deviceTable.size();
                QModelIndex bottomRight = createIndex(row.Srow, NBR_COLS_IN_TABLE);
                emit dataChanged(topLeft, bottomRight);
            

            Edit: it was pointed out that my row and column values were off by 1 each; I've corrected that (not reflected in the code above), and the behavior is unchanged.

            The field should update about once a second, but it updates whenever it loses or gains focus. Any suggestions are appreciated.

            kshegunovK Offline
            kshegunovK Offline
            kshegunov
            Moderators
            wrote on last edited by
            #20

            If I recall correctly, dataChanged should be enough to trigger the view to update. @VRonin can you work your magic here, what are we missing?

            Read and abide by the Qt Code of Conduct

            1 Reply Last reply
            1
            • VRoninV Offline
              VRoninV Offline
              VRonin
              wrote on last edited by
              #21
              • createIndex(); should be called only from index()
              • You never mentioned where you are potting the code above. In what method is it?

              But most importantly:
              model and view can not live on 2 different threads. The view will call methods from the model directly and that's a race condition

              "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
              3
              • VRoninV VRonin
                • createIndex(); should be called only from index()
                • You never mentioned where you are potting the code above. In what method is it?

                But most importantly:
                model and view can not live on 2 different threads. The view will call methods from the model directly and that's a race condition

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

                @VRonin

                1. noted (and changed) about createIndex().
                2. the code in I posted is part of an update routine. When this program receives a message from the target device, it updates the UI to reflect the information in the message. So, this code is in a method in my subclass of QAbstractTableModel.
                3. I wasn't aware that model/view had to be in the same thread. This will require some attention on my part.

                Thanks...

                VRoninV 1 Reply Last reply
                0
                • mzimmersM mzimmers

                  @VRonin

                  1. noted (and changed) about createIndex().
                  2. the code in I posted is part of an update routine. When this program receives a message from the target device, it updates the UI to reflect the information in the message. So, this code is in a method in my subclass of QAbstractTableModel.
                  3. I wasn't aware that model/view had to be in the same thread. This will require some attention on my part.

                  Thanks...

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

                  @mzimmers said in use of model/view programming:

                  the code in I posted is part of an update routine. When this program receives a message from the target device, it updates the UI to reflect the information in the message. So, this code is in a method in my subclass of QAbstractTableModel.

                  If that's how you update your model, why are going through the hell that is subclassing a model rather than just using QStandardItemModel?

                  "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
                  2
                  • VRoninV VRonin

                    @mzimmers said in use of model/view programming:

                    the code in I posted is part of an update routine. When this program receives a message from the target device, it updates the UI to reflect the information in the message. So, this code is in a method in my subclass of QAbstractTableModel.

                    If that's how you update your model, why are going through the hell that is subclassing a model rather than just using QStandardItemModel?

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

                    @VRonin: I'm new to model/view concepts, and needed an example. I used the address book example, which may not have been the best, but it was all I could find. And it uses the technique I tried to copy. I agree that it's been more trouble than I expected.

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

                      If you really want to gown that route I recommend chapter 3 of Advanced Qt Programming. There are traps everywhere when you 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
                      2
                      • mzimmersM Offline
                        mzimmersM Offline
                        mzimmers
                        wrote on last edited by
                        #26

                        What I really want is to keep this as simple as possible. Somehow, I get the impression that I've been less than fully successful so far in this endeavor.

                        The requirements of this project are modest enough: My UI must maintain a small table with information on an handful of devices that are wirelessly connected. Originally it seemed logical to contain the data model within the worker object, but SGaist and other Qt mavens have informed me this would be Doing It Wrong, so I'm looking at changing that. SGaist suggested my worker be part of my model class, but I don't yet understand the benefit of that. Would it be wrong to make the worker, widget and model classes all peers (and created in main())?

                        At this point, I'm not even sure I need threads, as my socket communications can be made entirely non-blocking.

                        kshegunovK 1 Reply Last reply
                        0
                        • mzimmersM mzimmers

                          What I really want is to keep this as simple as possible. Somehow, I get the impression that I've been less than fully successful so far in this endeavor.

                          The requirements of this project are modest enough: My UI must maintain a small table with information on an handful of devices that are wirelessly connected. Originally it seemed logical to contain the data model within the worker object, but SGaist and other Qt mavens have informed me this would be Doing It Wrong, so I'm looking at changing that. SGaist suggested my worker be part of my model class, but I don't yet understand the benefit of that. Would it be wrong to make the worker, widget and model classes all peers (and created in main())?

                          At this point, I'm not even sure I need threads, as my socket communications can be made entirely non-blocking.

                          kshegunovK Offline
                          kshegunovK Offline
                          kshegunov
                          Moderators
                          wrote on last edited by
                          #27

                          @mzimmers said in use of model/view programming:

                          SGaist suggested my worker be part of my model class, but I don't yet understand the benefit of that.

                          Only convenience. The idea is that you could, if needed, connect the worker's signals to object(s) internal to the model and vice versa.

                          Would it be wrong to make the worker, widget and model classes all peers (and created in main())?

                          Not at all, if you can cleanly do the connects between the components, there should be no compelling reason to have one of the objects be inside the other. Plus as your worker is the root object in a separate thread then it's free-floating, in the sense it can't have a parent, thus you don't really have anything to gain to have it anywhere but at the point where you create it and initialize the connects. After that the signal-slot mechanism, provided it was set up correctly, should do everything for you.

                          At this point, I'm not even sure I need threads, as my socket communications can be made entirely non-blocking.

                          If you are not sure then with 99% probability you don't. As you pointed out yourself most of the things can be used in a non-blocking manner, which lifts the need to have threading in most of the cases.

                          Read and abide by the Qt Code of Conduct

                          1 Reply Last reply
                          3

                          • Login

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • Users
                          • Groups
                          • Search
                          • Get Qt Extensions
                          • Unsolved