Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. how to change the model of a view
Forum Updated to NodeBB v4.3 + New Features

how to change the model of a view

Scheduled Pinned Locked Moved Solved QML and Qt Quick
9 Posts 5 Posters 760 Views 5 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 Offline
    mzimmersM Offline
    mzimmers
    wrote on last edited by
    #1

    Hi all -

    I have a QML view which is going to use one of two models. Which model isn't determined until relatively late in program startup. Here's the QML:

    ListModel {
      id: bottleModel_16
      ...
    }
    ListModel {
      id: bottleModel_19
      ...
    }
    Column {
      Repeater {
        model: (reagentManager.bottleList().length === 16) ? bottleModel_16 : bottleModel_19
      ...
    

    This doesn't work because the QML "executes" before the bottleList is populated, so the length returns as 0.

    So...what's a preferred method of updating the model? Not the model itself, but which one to use in the view? (Hopefully that's clear.)

    Thanks...

    ODБOïO J.HilkJ 2 Replies Last reply
    0
    • mzimmersM mzimmers

      Hi all -

      I have a QML view which is going to use one of two models. Which model isn't determined until relatively late in program startup. Here's the QML:

      ListModel {
        id: bottleModel_16
        ...
      }
      ListModel {
        id: bottleModel_19
        ...
      }
      Column {
        Repeater {
          model: (reagentManager.bottleList().length === 16) ? bottleModel_16 : bottleModel_19
        ...
      

      This doesn't work because the QML "executes" before the bottleList is populated, so the length returns as 0.

      So...what's a preferred method of updating the model? Not the model itself, but which one to use in the view? (Hopefully that's clear.)

      Thanks...

      ODБOïO Offline
      ODБOïO Offline
      ODБOï
      wrote on last edited by
      #2

      hi @mzimmers
      i would assign the model after bottle List is populated

      mzimmersM 1 Reply Last reply
      0
      • ODБOïO ODБOï

        hi @mzimmers
        i would assign the model after bottle List is populated

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

        @LeLev the architecture of this application is such that all the QML views are loaded up front, not on an "as needed" basis. Is it possible to re-assign the model?

        Thanks...

        ODБOïO 1 Reply Last reply
        0
        • mzimmersM mzimmers

          @LeLev the architecture of this application is such that all the QML views are loaded up front, not on an "as needed" basis. Is it possible to re-assign the model?

          Thanks...

          ODБOïO Offline
          ODБOïO Offline
          ODБOï
          wrote on last edited by
          #4

          @mzimmers said in how to change the model of a view:

          Is it possible to re-assign the model?

          why not try it ? :) I think it is possible

          1 Reply Last reply
          0
          • jeremy_kJ Offline
            jeremy_kJ Offline
            jeremy_k
            wrote on last edited by
            #5

            Use a property that changes when the list length does as part of the binding. It would be convenient if that property happened to be the length or at involved in fetching it, but it doesn't have to be. Perhaps reagentManager is that property.

            model: (reagentManger.bottleList().length + reagentManager.zeroValueProperty === 16) ? bottleModel_16 : bottleModel_19
            

            Or emit a signal and reassign the model in a connected slot.

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

            1 Reply Last reply
            1
            • mzimmersM mzimmers

              Hi all -

              I have a QML view which is going to use one of two models. Which model isn't determined until relatively late in program startup. Here's the QML:

              ListModel {
                id: bottleModel_16
                ...
              }
              ListModel {
                id: bottleModel_19
                ...
              }
              Column {
                Repeater {
                  model: (reagentManager.bottleList().length === 16) ? bottleModel_16 : bottleModel_19
                ...
              

              This doesn't work because the QML "executes" before the bottleList is populated, so the length returns as 0.

              So...what's a preferred method of updating the model? Not the model itself, but which one to use in the view? (Hopefully that's clear.)

              Thanks...

              J.HilkJ Online
              J.HilkJ Online
              J.Hilk
              Moderators
              wrote on last edited by
              #6

              @mzimmers
              this looks like bottleList is an Invokable function rather than a property, which is the problem

              model: (reagentManager.bottleList().length === 16) ? bottleModel_16 : bottleModel_19

              its is check only once, onCreation.
              Make the length of the model a proper Q_PROPERTY and it should work just fine:

              model: (reagentManager.bottleListLength === 16) ? bottleModel_16 : bottleModel_19

              or make the bottleList a correct Q_PROPERTY and this should work as well:

              model: (reagentManager.bottleList.length === 16) ? bottleModel_16 : bottleModel_19


              Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


              Q: What's that?
              A: It's blue light.
              Q: What does it do?
              A: It turns blue.

              mzimmersM 1 Reply Last reply
              4
              • J.HilkJ J.Hilk

                @mzimmers
                this looks like bottleList is an Invokable function rather than a property, which is the problem

                model: (reagentManager.bottleList().length === 16) ? bottleModel_16 : bottleModel_19

                its is check only once, onCreation.
                Make the length of the model a proper Q_PROPERTY and it should work just fine:

                model: (reagentManager.bottleListLength === 16) ? bottleModel_16 : bottleModel_19

                or make the bottleList a correct Q_PROPERTY and this should work as well:

                model: (reagentManager.bottleList.length === 16) ? bottleModel_16 : bottleModel_19

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

                @J-Hilk I would like very much to make my bottle list object a Q_PROPERTY. In fact, that was my first attempt, but I ran into problems. Here's my source code:

                struct Bottle : public QObject {
                  ...
                   
                typedef QList<Bottle *> Bottles;
                
                class ReagentManager : public QObject {
                  Q_OBJECT
                  private:
                  Bottles m_bottleList;
                public:
                  Q_PROPERTY(Bottles bottleList
                             READ getBottleList
                             MEMBER m_bottleList)
                  ...
                

                And my QML:

                Column {
                  id: bottles
                  Repeater {
                  model: (reagentManager.bottleList.length === 19) ? bottleModel_19 : bottleModel_16
                

                I get a runtime error:

                TypeError: Cannot read property 'length' of undefined
                

                On the line that attempts to use the length property.

                1 Reply Last reply
                0
                • fcarneyF Offline
                  fcarneyF Offline
                  fcarney
                  wrote on last edited by
                  #8

                  @mzimmers said in how to change the model of a view:

                  Q_PROPERTY(Bottles bottleList

                  Make your QML facing list a list of QObject*. Or register Bottles and Bottle with the meta object system.

                  Q_PROPERTY(QList<QObject*> bottleList
                  

                  This means your getBottleList will have to build up a QList<QObject> list each time.

                  C++ is a perfectly valid school of magic.

                  mzimmersM 1 Reply Last reply
                  2
                  • fcarneyF fcarney

                    @mzimmers said in how to change the model of a view:

                    Q_PROPERTY(Bottles bottleList

                    Make your QML facing list a list of QObject*. Or register Bottles and Bottle with the meta object system.

                    Q_PROPERTY(QList<QObject*> bottleList
                    

                    This means your getBottleList will have to build up a QList<QObject> list each time.

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

                    @fcarney yeah, I realized that I'd made a couple of mistakes in my header file.

                    typedef QList<Bottle *> Bottles;
                    Q_DECLARE_METATYPE(Bottles)
                    ...
                    Q_PROPERTY(Bottles bottleList
                               MEMBER m_bottleList
                               NOTIFY bottleListChanged)
                    signals:
                      void bottleListChanged();
                    

                    The signal is emitted at the end of an updater routine that's called from QML when the view becomes visible:

                        onVisibleChanged: {
                          if (visible) {
                            reagentManager.updateBottleList()
                    

                    I got an error when I tried to declare Bottle as a metatype (possibly because it's a struct, not a class), but the program seems to work without that.

                    So, declaring the metatype greatly simplified the code, and the signal handles the update. Thanks for the help!

                    1 Reply Last reply
                    2

                    • Login

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