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. Interacting with model data directly or via the model's interface.
Forum Updated to NodeBB v4.3 + New Features

Interacting with model data directly or via the model's interface.

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

    I'll use the following scenario to give context to my question:

    Suppose I have a subclass of QAbstractListModel, JourneyListModel, which is used by a QML list view to display status data contained in the model's QList of Journey objects. The Journey class has many methods, loadJourney(), clearJourney(), setDestination(), setRoute(), etc, with many of those methods resulting in data changes we'd wish to display.

    Supposedly, best practice entails interacting with the the model's objects via the model's interface and not exposing non-const references to the underlying data outside of the model, but this approach doesn't sit right with me.

    For every method in Journey, there would need to be a corresponding method in the model's interface. As Journey's functionality grows (with potentially many methods which don't cause displayable data changes), it becomes increasingly difficult to maintain this. Furthermore, I fear that "protecting" the Journey objects behind the model may restrict, or complicate, future development. Journey's methods need to be called from many directions: the UI, incoming network data managed by another class, whatever...

    Here I propose what I consider to be a cleaner alternative:

    JourneyListModel does not have ownership of the Journey objects, but rather holds a list of pointers to the objects which are held in QList<Journey> in another class, JourneyManager. JourneyManager is responsible for creating and deleting Journey objects. Both operations emit signals, passing a pointer to the newly created/deleted Journey object. A slot in the model connects to these signals and calls begininsertrows(), etc.

    JourneyManager can provide other modules with a non-const pointer to a requested Journey object that they can interact with directly. As for notifying the model that data has changed, well... Have Journey emit a journeyUpdated() signal where needed, and connect a slot in the model to the signal when the object is created. This way users of Journey do not need to concern themselves with updating the model or emitting dataChanged().

    Is this approach sensible, or should I follow "good practice" and do it the prescribed way?

    jeremy_kJ 1 Reply Last reply
    0
    • E ECEC

      I'll use the following scenario to give context to my question:

      Suppose I have a subclass of QAbstractListModel, JourneyListModel, which is used by a QML list view to display status data contained in the model's QList of Journey objects. The Journey class has many methods, loadJourney(), clearJourney(), setDestination(), setRoute(), etc, with many of those methods resulting in data changes we'd wish to display.

      Supposedly, best practice entails interacting with the the model's objects via the model's interface and not exposing non-const references to the underlying data outside of the model, but this approach doesn't sit right with me.

      For every method in Journey, there would need to be a corresponding method in the model's interface. As Journey's functionality grows (with potentially many methods which don't cause displayable data changes), it becomes increasingly difficult to maintain this. Furthermore, I fear that "protecting" the Journey objects behind the model may restrict, or complicate, future development. Journey's methods need to be called from many directions: the UI, incoming network data managed by another class, whatever...

      Here I propose what I consider to be a cleaner alternative:

      JourneyListModel does not have ownership of the Journey objects, but rather holds a list of pointers to the objects which are held in QList<Journey> in another class, JourneyManager. JourneyManager is responsible for creating and deleting Journey objects. Both operations emit signals, passing a pointer to the newly created/deleted Journey object. A slot in the model connects to these signals and calls begininsertrows(), etc.

      JourneyManager can provide other modules with a non-const pointer to a requested Journey object that they can interact with directly. As for notifying the model that data has changed, well... Have Journey emit a journeyUpdated() signal where needed, and connect a slot in the model to the signal when the object is created. This way users of Journey do not need to concern themselves with updating the model or emitting dataChanged().

      Is this approach sensible, or should I follow "good practice" and do it the prescribed way?

      jeremy_kJ Offline
      jeremy_kJ Offline
      jeremy_k
      wrote on last edited by
      #2

      @ECEC said in Interacting with model data directly or via the model's interface.:

      Supposedly, best practice entails interacting with the the model's objects via the model's interface and not exposing non-const references to the underlying data outside of the model, but this approach doesn't sit right with me.

      Do you have a link to an example of this advice? The internet is full of all sorts of suggestions. Maybe with a little context, the author's POV will make more sense.

      Asking a question about code? http://eel.is/iso-c++/testcase/

      E 1 Reply Last reply
      1
      • jeremy_kJ jeremy_k

        @ECEC said in Interacting with model data directly or via the model's interface.:

        Supposedly, best practice entails interacting with the the model's objects via the model's interface and not exposing non-const references to the underlying data outside of the model, but this approach doesn't sit right with me.

        Do you have a link to an example of this advice? The internet is full of all sorts of suggestions. Maybe with a little context, the author's POV will make more sense.

        E Offline
        E Offline
        ECEC
        wrote on last edited by
        #3

        @jeremy_k

        Not to hand, but it's definitely an opinion I've seen multiple times. I'm reassured though by your comment that other methods can also be acceptable. What did you think of my suggested approach?

        SGaistS 1 Reply Last reply
        0
        • E ECEC

          @jeremy_k

          Not to hand, but it's definitely an opinion I've seen multiple times. I'm reassured though by your comment that other methods can also be acceptable. What did you think of my suggested approach?

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

          Your approach has its merits but it also implies that the class of your object must derive from QObject which has an overhead to take into account.

          For changing the data of your object, one classic way to do it is through custom roles. That way you don't need to add new APIs to your model. In the the absolute, the model should be a thin wrapper around your data structure providing a simple API to help manage the objects.

          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
          0
          • SGaistS SGaist

            Your approach has its merits but it also implies that the class of your object must derive from QObject which has an overhead to take into account.

            For changing the data of your object, one classic way to do it is through custom roles. That way you don't need to add new APIs to your model. In the the absolute, the model should be a thin wrapper around your data structure providing a simple API to help manage the objects.

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

            @SGaist

            I certainly intend to use custom roles to display the data to the list view (or grid view), but the status data isn't changed via the view, but from other ares of the system, most likely data coming in over the network. So, there still needs to be some other mechanism to set this and update the model. For added info, each object is updated 10/sec with data from the network, and there are a maximum of 255 objects. Would inheriting from Q_Object be too much of an overhead in this case?

            SGaistS 1 Reply Last reply
            0
            • E ECEC

              @SGaist

              I certainly intend to use custom roles to display the data to the list view (or grid view), but the status data isn't changed via the view, but from other ares of the system, most likely data coming in over the network. So, there still needs to be some other mechanism to set this and update the model. For added info, each object is updated 10/sec with data from the network, and there are a maximum of 255 objects. Would inheriting from Q_Object be too much of an overhead in this case?

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

              With that number it's fine.

              You know that you can use custom roles for both reading and setting data ?

              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
              0
              • SGaistS SGaist

                With that number it's fine.

                You know that you can use custom roles for both reading and setting data ?

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

                @SGaist

                Do you mean via setData? If so, it's not as nice an API as I could have if I had dedicated methods on the objects for setting specific variables, performing calculations and then setting, etc. Would you agree?

                I appreciate it's hard to quantify with the limited info I've given you, but very approximately, how many objects inheriting Q_OBJECT would it take for you to be concerned about overhead?

                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