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. Howto reset QML interface
Forum Updated to NodeBB v4.3 + New Features

Howto reset QML interface

Scheduled Pinned Locked Moved Solved QML and Qt Quick
11 Posts 3 Posters 1.2k Views 1 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.
  • P Offline
    P Offline
    pingal
    wrote on last edited by pingal
    #1

    Initially I used this approach for resetting my model every time somethings changed in class1.

    Class class1: public QObject{
    .
    .
    private:
    QQmlApplicationEngine mEngine;
    void resetModel ( );
    }
    
    class1::resetModel ( ) {
        mEngine.rootContext()->setContextProperty("class1ExposedObj", this);
    }
    

    This approach works fine for me but now I've another class, say class2 which also needs to be exposed to QML. So I thought I should put mEngine in my main.cpp and define resetModel() outside class.

    void resetModel(QQmlApplicationEngine &mEngine ,QList<QObject *> myObjects){
      
        mEngine.rootContext()->setContextProperty("class1",myObjects[1]);
        mEngine.rootContext()->setContextProperty("class2",myObjects[2]);
        .
        .
        .
        mEngine.rootContext()->setContextProperty("classN",myObjects[n]);
    }
    

    Is their a better approach of resetModel() ?

    J.HilkJ raven-worxR 2 Replies Last reply
    0
    • P pingal

      Initially I used this approach for resetting my model every time somethings changed in class1.

      Class class1: public QObject{
      .
      .
      private:
      QQmlApplicationEngine mEngine;
      void resetModel ( );
      }
      
      class1::resetModel ( ) {
          mEngine.rootContext()->setContextProperty("class1ExposedObj", this);
      }
      

      This approach works fine for me but now I've another class, say class2 which also needs to be exposed to QML. So I thought I should put mEngine in my main.cpp and define resetModel() outside class.

      void resetModel(QQmlApplicationEngine &mEngine ,QList<QObject *> myObjects){
        
          mEngine.rootContext()->setContextProperty("class1",myObjects[1]);
          mEngine.rootContext()->setContextProperty("class2",myObjects[2]);
          .
          .
          .
          mEngine.rootContext()->setContextProperty("classN",myObjects[n]);
      }
      

      Is their a better approach of resetModel() ?

      J.HilkJ Offline
      J.HilkJ Offline
      J.Hilk
      Moderators
      wrote on last edited by J.Hilk
      #2

      @pingal said in Howto reset QML interface:

      Is their a better approach of resetModel() ?

      yes, use a proper c++ model, like a QAbstractListModel.

      The models have reset, and changed signals that the QML Views correctly react to


      The cheap way would be to make a parent "ContextPropertyClass" and add your QLists of QObject* as A QVariant property. Then an emit of your defined changed signals will cause a reevaluation of the property.


      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.

      1 Reply Last reply
      0
      • P pingal

        Initially I used this approach for resetting my model every time somethings changed in class1.

        Class class1: public QObject{
        .
        .
        private:
        QQmlApplicationEngine mEngine;
        void resetModel ( );
        }
        
        class1::resetModel ( ) {
            mEngine.rootContext()->setContextProperty("class1ExposedObj", this);
        }
        

        This approach works fine for me but now I've another class, say class2 which also needs to be exposed to QML. So I thought I should put mEngine in my main.cpp and define resetModel() outside class.

        void resetModel(QQmlApplicationEngine &mEngine ,QList<QObject *> myObjects){
          
            mEngine.rootContext()->setContextProperty("class1",myObjects[1]);
            mEngine.rootContext()->setContextProperty("class2",myObjects[2]);
            .
            .
            .
            mEngine.rootContext()->setContextProperty("classN",myObjects[n]);
        }
        

        Is their a better approach of resetModel() ?

        raven-worxR Offline
        raven-worxR Offline
        raven-worx
        Moderators
        wrote on last edited by raven-worx
        #3

        @pingal said in Howto reset QML interface:

        Initially I used this approach for resetting my model every time somethings changed in class1.

        what changes in your classes and how do you use them in QML?
        if you talk about properties of the object then you should add a NOTIFY signal to all your objects properties and trigger it instead of setting the the whole object again.

        or if you would change the objects itself (new instance everytime) you could add a single wrapper object with a property containing all your object as a list object using QQmlListProperty and reset this list (clear and add objects again).

        --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
        If you have a question please use the forum so others can benefit from the solution in the future

        1 Reply Last reply
        0
        • P Offline
          P Offline
          pingal
          wrote on last edited by pingal
          #4

          @J-Hilk :
          I would look into QAbstractListModel as you stated.

          @raven-worx :
          "if you would change the objects itself (new instance everytime) you could add a single wrapper object with a property containing all your object as a list object using QQmlListProperty and reset this list (clear and add objects again)"

          I'm exactly doing that. class1 is a wrapper actually, which notify (using QProperty) QML every time an object is modified/removed and it works.
          I read somewhere that resetting the view just require you to call setContextProperty for that corresponding instance as i have described in the above post i.e. resetModel() in class1.

          Now I need resetModel() to be placed such that when i call it, it should call setContextProperty for all objects, not just class1.

          raven-worxR 1 Reply Last reply
          0
          • P pingal

            @J-Hilk :
            I would look into QAbstractListModel as you stated.

            @raven-worx :
            "if you would change the objects itself (new instance everytime) you could add a single wrapper object with a property containing all your object as a list object using QQmlListProperty and reset this list (clear and add objects again)"

            I'm exactly doing that. class1 is a wrapper actually, which notify (using QProperty) QML every time an object is modified/removed and it works.
            I read somewhere that resetting the view just require you to call setContextProperty for that corresponding instance as i have described in the above post i.e. resetModel() in class1.

            Now I need resetModel() to be placed such that when i call it, it should call setContextProperty for all objects, not just class1.

            raven-worxR Offline
            raven-worxR Offline
            raven-worx
            Moderators
            wrote on last edited by
            #5

            @pingal said in Howto reset QML interface:

            I'm exactly doing that. class1 is a wrapper actually, which notify (using QProperty) QML every time an object is modified/removed and it works

            and why do you want to reset the object again with setContextProperty ?!

            --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
            If you have a question please use the forum so others can benefit from the solution in the future

            1 Reply Last reply
            0
            • P Offline
              P Offline
              pingal
              wrote on last edited by pingal
              #6

              @raven-worx : "why do you want to reset the object again with setContextProperty ?!"

              I think I've not clear the program structure clearly. I will explain it by an example.

              Lets say I've a CAR Class

              Class Car : public QObject {
              .
              Q_PROPERTY(QString color READ color WRITE setColor NOTIFY colorChanged)
              .
              .
              attributes
              .
              }
              

              My objective was to list individual cars along with its attribute in my ListView. So I wrapped my CAR class with another class let say CarWrapper.

              Class CarWrapper : public QObject{
              
              Q_PROPERTY(QList<QObject*> myCar READ myCar WRITE setmyCar  NOTIFY myCarChanged)
              .
              .
              signals:
              void resetModel();
              
              public slots:
              void onAddCar(newCar);
              void RemoveCar(RemoveCarId);
              }
              
              void CarWrapper::resetModel()
              {
                  mEngine.rootContext()->setContextProperty("CarWrapper", this);
              }
              

              PS: So every time CarWrapper::onAddCar() or CarWrapper::RemoveCar() is called, resetModel() is called within these functions to update the view

              raven-worxR 1 Reply Last reply
              0
              • P pingal

                @raven-worx : "why do you want to reset the object again with setContextProperty ?!"

                I think I've not clear the program structure clearly. I will explain it by an example.

                Lets say I've a CAR Class

                Class Car : public QObject {
                .
                Q_PROPERTY(QString color READ color WRITE setColor NOTIFY colorChanged)
                .
                .
                attributes
                .
                }
                

                My objective was to list individual cars along with its attribute in my ListView. So I wrapped my CAR class with another class let say CarWrapper.

                Class CarWrapper : public QObject{
                
                Q_PROPERTY(QList<QObject*> myCar READ myCar WRITE setmyCar  NOTIFY myCarChanged)
                .
                .
                signals:
                void resetModel();
                
                public slots:
                void onAddCar(newCar);
                void RemoveCar(RemoveCarId);
                }
                
                void CarWrapper::resetModel()
                {
                    mEngine.rootContext()->setContextProperty("CarWrapper", this);
                }
                

                PS: So every time CarWrapper::onAddCar() or CarWrapper::RemoveCar() is called, resetModel() is called within these functions to update the view

                raven-worxR Offline
                raven-worxR Offline
                raven-worx
                Moderators
                wrote on last edited by
                #7

                @pingal
                for exactly this case you should use QQmlListProperty

                --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                If you have a question please use the forum so others can benefit from the solution in the future

                1 Reply Last reply
                0
                • P Offline
                  P Offline
                  pingal
                  wrote on last edited by pingal
                  #8

                  I will look into QQmlListProperty, But for now I've created ContextPropertyClass as below

                  class ContextPropertyClass: public QObject{
                  
                  public:
                      ContextPropertyClass(QObject *parent = nullptr);
                      bool initialize();
                      QList<QObject *> myObjects;
                  
                  public slots:
                      void resetModel();
                  
                  private:
                      QQmlApplicationEngine mEngine;
                  
                  };
                  
                  bool ContextPropertyClass::initialize(){
                  
                      resetModel();
                      mEngine.load(QUrl(QStringLiteral("qrc:/mvc.qml")));
                      if (mEngine.rootObjects().isEmpty())
                          return false;
                  
                      return true;
                  }
                  
                  
                  void ContextPropertyClass::resetModel(){
                  
                      mEngine.rootContext()->setContextProperty("class1",myObjects[0]);
                      mEngine.rootContext()->setContextProperty("class1",myObjects[1]);
                  .
                  .
                  mEngine.rootContext()->setContextProperty("classN",myObjects[N]);
                  }
                  

                  A temporary solution for now.

                  Thanks for helpful suggestions.

                  raven-worxR 1 Reply Last reply
                  0
                  • P pingal

                    I will look into QQmlListProperty, But for now I've created ContextPropertyClass as below

                    class ContextPropertyClass: public QObject{
                    
                    public:
                        ContextPropertyClass(QObject *parent = nullptr);
                        bool initialize();
                        QList<QObject *> myObjects;
                    
                    public slots:
                        void resetModel();
                    
                    private:
                        QQmlApplicationEngine mEngine;
                    
                    };
                    
                    bool ContextPropertyClass::initialize(){
                    
                        resetModel();
                        mEngine.load(QUrl(QStringLiteral("qrc:/mvc.qml")));
                        if (mEngine.rootObjects().isEmpty())
                            return false;
                    
                        return true;
                    }
                    
                    
                    void ContextPropertyClass::resetModel(){
                    
                        mEngine.rootContext()->setContextProperty("class1",myObjects[0]);
                        mEngine.rootContext()->setContextProperty("class1",myObjects[1]);
                    .
                    .
                    mEngine.rootContext()->setContextProperty("classN",myObjects[N]);
                    }
                    

                    A temporary solution for now.

                    Thanks for helpful suggestions.

                    raven-worxR Offline
                    raven-worxR Offline
                    raven-worx
                    Moderators
                    wrote on last edited by
                    #9

                    @pingal
                    i still dont get why you want to set the context properties over and over again when every property already has a notifier signal...

                    --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                    If you have a question please use the forum so others can benefit from the solution in the future

                    P 2 Replies Last reply
                    0
                    • raven-worxR raven-worx

                      @pingal
                      i still dont get why you want to set the context properties over and over again when every property already has a notifier signal...

                      P Offline
                      P Offline
                      pingal
                      wrote on last edited by
                      #10
                      This post is deleted!
                      1 Reply Last reply
                      0
                      • raven-worxR raven-worx

                        @pingal
                        i still dont get why you want to set the context properties over and over again when every property already has a notifier signal...

                        P Offline
                        P Offline
                        pingal
                        wrote on last edited by pingal
                        #11

                        @raven-worx
                        Q_PROPERTY will notify the view about the changes. At first I thought that my cpp logic can change the objects and in-order to reflect those changes in QML, I've to reset the ContextProperty() but now I understood, I don't need resetModel() at all as Q_PROPERTY notify signal will done this behind the scenes.

                        Thanks

                        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