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
Qt 6.11 is out! See what's new in the release blog

Using same qml for multiple instantiation

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
qml
14 Posts 3 Posters 5.1k 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 Offline
    sierdzioS Offline
    sierdzio
    Moderators
    wrote on last edited by
    #2

    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.

    (Z(:^

    M 1 Reply Last reply
    3
    • ODБOïO Offline
      ODБOïO Offline
      ODБOï
      wrote on last edited by
      #3

      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 1 Reply Last reply
      2
      • 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