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. Using same qml for multiple instantiation

Using same qml for multiple instantiation

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
qml
14 Posts 3 Posters 4.8k 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.
  • sierdzioS sierdzio

    Yes. This is exactly what happens when you're using a C++ model (QAbstractItemModel) with views: Repeater, ListView, GridView etc.

    You can also use same component with different data in Loader, SwipeView, TabView etc.

    M Offline
    M Offline
    milan
    wrote on last edited by
    #4

    Hello @sierdzio. Thank you for reply. So, there is single C++ model (QAbstractItemModel) feeding items in GridView, ListView, Repeater? What datastructure should I choose (suppose if I chose GridView as view). Is QVariantList good idea for the GridView.Could you give me a example or link so I could check. Thank you.

    sierdzioS 1 Reply Last reply
    0
    • M milan

      Hello @sierdzio. Thank you for reply. So, there is single C++ model (QAbstractItemModel) feeding items in GridView, ListView, Repeater? What datastructure should I choose (suppose if I chose GridView as view). Is QVariantList good idea for the GridView.Could you give me a example or link so I could check. Thank you.

      sierdzioS Offline
      sierdzioS Offline
      sierdzio
      Moderators
      wrote on last edited by
      #5

      @milan said in Using same qml for multiple instantiation:

      Hello @sierdzio. Thank you for reply. So, there is single C++ model (QAbstractItemModel) feeding items in GridView, ListView, Repeater? What datastructure should I choose (suppose if I chose GridView as view). Is QVariantList good idea for the GridView.Could you give me a example or link so I could check. Thank you.

      Answer depends entirely on what you are trying to achieve. An introduction to this topic can be found here.

      Info about using C++ data models can be found here.

      (Z(:^

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

        Hi @milan
        Yes this is possible,
        if your .qml file/component defined like this :

        //Mycomponent.qml
        
        Item{
        property string m_name 
        }
        

        you can do :

        Mycomponent{
        id:c1
        m_name : cppObj.name1  // assuming you have an object called cppObj reachable in QML with Q_Property *name1*
        }
        Mycomponent{
        id:c2
        m_name : cppObj.name2
        }
        
        M Offline
        M Offline
        milan
        wrote on last edited by
        #6

        @LeLev. Thank you for your reply. You are using Q_PROPERTY. Is it possible using QAbstractItemModel? If I use Q_PROPERTY, I need to use a lot of Q_PROPERTY. Because I have around 50 variables which needs to be displayed in the UI. But not all 50 variables has to be displayed, only the variables chosen by the user while the application is running. So, which variables is chosen is not known until the application is run and user chooses the variables

        ODБOïO 1 Reply Last reply
        0
        • M milan

          @LeLev. Thank you for your reply. You are using Q_PROPERTY. Is it possible using QAbstractItemModel? If I use Q_PROPERTY, I need to use a lot of Q_PROPERTY. Because I have around 50 variables which needs to be displayed in the UI. But not all 50 variables has to be displayed, only the variables chosen by the user while the application is running. So, which variables is chosen is not known until the application is run and user chooses the variables

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

          hi @milan yes of course you can use QAbstractItemModel if you want

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

            hi @milan yes of course you can use QAbstractItemModel if you want

            M Offline
            M Offline
            milan
            wrote on last edited by
            #8

            @LeLev @sierdzio. Thanks to both of you. I created following:

            #include <QGuiApplication>
            #include <QQmlApplicationEngine>
            #include <QQmlContext>
            
            #include <model.h>
            
            int main(int argc, char *argv[])
            {
                QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
            
                QGuiApplication app(argc, argv);
            
                QQmlApplicationEngine* engine = new QQmlApplicationEngine();
                Model firstmodel("FirstModel");
                Model secondmodel("SecondModel");
            
                engine->rootContext()->setContextProperty("FirstModel", &firstmodel);
                engine->rootContext()->setContextProperty("SecondModel", &secondmodel);
            
                engine->load(QUrl(QStringLiteral("qrc:/main.qml")));
                if (engine->rootObjects().isEmpty())
                    return -1;
                return app.exec();
            }
            
            #ifndef MODEL_H
            #define MODEL_H
            
            #include <QObject>
            #include <QTimer>
            #include <QDebug>
            
            class Model : public QObject
            {
                Q_OBJECT
                Q_PROPERTY(int num READ num WRITE setNum NOTIFY numChanged)
            
            public:
                explicit Model(QString name, QObject *parent = nullptr);
                ~Model();
            
                int num() const;
            signals:
                void numChanged(int num);
                void operate();
            
            public slots:
                void setNum(int num);
                void update();
            
            private:
                QString m_name;
                int m_num;
                QTimer* m_timer;
            };
            
            #endif // MODEL_H
            
            #include "model.h"
            
            Model::Model(QString name, QObject *parent) : QObject (parent)
            {
                m_num = 10;
                m_name = name;
                qDebug() << "Creating Model:" << m_name;
                m_timer = new QTimer(this);
                connect(m_timer, SIGNAL(timeout()), this, SLOT(update()));
                m_timer->start(1000);
            }
            
            Model::~Model()
            {
                qDebug() << "Destructing Model:" << m_name;
            }
            
            int Model::num() const
            {
                return m_num;
            }
            
            void Model::update()
            {
                m_num += 5;
                this->setNum(m_num);
                qDebug() << "Updating" << m_name << m_num;
                emit numChanged(m_num);
            
                if (m_num == 100) {
                    m_timer->stop();
                    qDebug() << "Timer is stopped";
                }
            }
            
            void Model::setNum(int num)
            {
                if (m_num == num)
                    return;
                qDebug() << "Setting value:" << num;
                m_num = num;
                emit numChanged(m_num);
            }
            
            import QtQuick 2.9
            import QtQuick.Controls 2.4
            import QtQuick.Layouts 1.11
            import QtQuick.Controls.Styles 1.4
            import QtQuick.Extras 1.4
            
            ApplicationWindow {
                visible: true
                width: 640
                height: 480
                title: qsTr("App")
            
                Gauge {
                    x: 10
                    y: 10
                    minimumValue: 0
                    value: FirstModel.num
                    maximumValue: 100
                }
                Gauge {
                    x: 100
                    y: 10
                    minimumValue: 0
                    value: SecondModel.num
                    maximumValue: 100
                }
            }
            

            From the above code, I can use most of Gauge element (qml) again, but you can also see that it is hard coded at value. What I would like to do is "creating a C++ model object dynamically when it needs to be constructed and this should trigger to add corresponding Gauge element(qml) in QML window application."

            1 Reply Last reply
            0
            • sierdzioS Offline
              sierdzioS Offline
              sierdzio
              Moderators
              wrote on last edited by
              #9

              @milan said in Using same qml for multiple instantiation:

              What I would like to do is "creating a C++ model object dynamically when it needs to be constructed and this should trigger to add corresponding Gauge element(qml) in QML window application."

              Either add some signals/slots to invoke Qt.createComponent() in QML in response to C++ object being created. Or use a grid & model as mentioned earlier (then if Gauge is the delegate it will be created automatically when you add new element to the model). Or inject your C++ object into QML engine (by adding it to children of your root element for example) - but that is hacky and hard to do.

              (Z(:^

              M 1 Reply Last reply
              1
              • sierdzioS sierdzio

                @milan said in Using same qml for multiple instantiation:

                What I would like to do is "creating a C++ model object dynamically when it needs to be constructed and this should trigger to add corresponding Gauge element(qml) in QML window application."

                Either add some signals/slots to invoke Qt.createComponent() in QML in response to C++ object being created. Or use a grid & model as mentioned earlier (then if Gauge is the delegate it will be created automatically when you add new element to the model). Or inject your C++ object into QML engine (by adding it to children of your root element for example) - but that is hacky and hard to do.

                M Offline
                M Offline
                milan
                wrote on last edited by
                #10

                @sierdzio . Thanks, yes adding delegate works with single element. So, I added QList<int> to Q_PROPERTY. How can I access each element in QML?

                    GridView {
                        width: 300; height: 200
                        model:  FirstModel
                        delegate: Gauge {
                            x: 10
                            y: 10
                            minimumValue: 0
                            value: num[0] // how to add more elements
                            maximumValue: 100
                        }
                    }
                
                    Q_PROPERTY(QList<int> num READ num WRITE setNum NOTIFY numChanged)
                
                1 Reply Last reply
                0
                • sierdzioS Offline
                  sierdzioS Offline
                  sierdzio
                  Moderators
                  wrote on last edited by
                  #11

                  What is FirstModel?

                  (Z(:^

                  M 1 Reply Last reply
                  0
                  • sierdzioS sierdzio

                    What is FirstModel?

                    M Offline
                    M Offline
                    milan
                    wrote on last edited by
                    #12

                    Hello @sierdzio,

                       QQmlApplicationEngine* engine = new QQmlApplicationEngine();
                       Model firstmodel("FirstModel", 3);
                       engine->rootContext()->setContextProperty("FirstModel", &firstmodel);
                       engine->load(QUrl(QStringLiteral("qrc:/main.qml")));
                    

                    FirstModel is just name of object with 3 QList int items in Model Class.

                    1 Reply Last reply
                    0
                    • sierdzioS Offline
                      sierdzioS Offline
                      sierdzio
                      Moderators
                      wrote on last edited by
                      #13

                      Ok, so that is a bit wrong.

                      Either change your Model into a proper model (QAbstractItemModel or QListItemModel etc.). Or (easier) set the num property as model, like this:

                      GridView {
                              width: 300; height: 200
                              model:  FirstModel.num
                              delegate: Gauge {
                                  x: 10
                                  y: 10
                                  minimumValue: 0
                                  value: modelData
                                  maximumValue: 100
                              }
                          }
                      

                      Untested.

                      how to add more elements

                      Use FirstModel.setNum to modify your list.

                      (Z(:^

                      M 1 Reply Last reply
                      0
                      • sierdzioS sierdzio

                        Ok, so that is a bit wrong.

                        Either change your Model into a proper model (QAbstractItemModel or QListItemModel etc.). Or (easier) set the num property as model, like this:

                        GridView {
                                width: 300; height: 200
                                model:  FirstModel.num
                                delegate: Gauge {
                                    x: 10
                                    y: 10
                                    minimumValue: 0
                                    value: modelData
                                    maximumValue: 100
                                }
                            }
                        

                        Untested.

                        how to add more elements

                        Use FirstModel.setNum to modify your list.

                        M Offline
                        M Offline
                        milan
                        wrote on last edited by milan
                        #14

                        @sierdzio. Thank you for your answer. I tried as you suggested with

                        GridView {
                                width: 300; height: 200
                                model:  FirstModel.num
                                delegate: Gauge {
                                    x: 10
                                    y: 10
                                    minimumValue: 0
                                    value: modelData
                                    maximumValue: 100
                                }
                            }
                        

                        But I see nothing in the GUI. I will surely try later with QAbstractItemModel you suggested.

                        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