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. Dynamically create a whole new QML object from C++
Forum Updated to NodeBB v4.3 + New Features

Dynamically create a whole new QML object from C++

Scheduled Pinned Locked Moved Solved QML and Qt Quick
qtquickc++qml
7 Posts 2 Posters 8.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.
  • B Offline
    B Offline
    bguivarch
    wrote on 5 Sept 2016, 09:30 last edited by
    #1

    Hello everyone,

    I have a QML component Foo defined it its own file foo.qml. In my QtQuick app, I need to dynamically create instances of this component as a respond of a user action. I was able to do it using Qt.createQmlObject().

    Now I want to have a matching C++ object with exposed properties/methods so when the QML component Foo is changed, its C++ equivalent is updated. To do so, I have created a C++ class FooModel that subclasses QtQuickItem and registered my C++ new type using qmlRegisterType().

    My problem is : I want to dynamically instanciate FooModel and as a result, have a Foo component to be created in the QML side of the application, so no more use of Qt.createQmlObject(). And when I say instanciate, I mean to fully define the Foo component in my C++ object, and not loading foo.qml using QQmlComponent.create(). The idea behind this is to get rid of the foo.qml file.

    I looked into the documentation and the Internet, but I cannot find any example that matches my need.
    So my questions are :
    -is it possible to fully create a QML component from C++,? Something like :

    Rect* rect = new Rect(QMLRoot);
    Text* text = new Text(rect);
    MouseArea* marea = new MouseArea(rect);
    

    -if it is possible, how can you handle events, for example how do you plug to MouseArea events?

    I have the feeling that I am trying to do something that is not possible, but I am not a Qt expert so I am looking for your advices.
    Thanks for any help!

    1 Reply Last reply
    0
    • J Offline
      J Offline
      jeremy_k
      wrote on 5 Sept 2016, 21:35 last edited by
      #2

      Defining a visual QML component in C++ is done by inheriting from QQuickItem. Look for the "Custom Scene Graph Items" section.

      Unfortunately most (all?) of the building blocks such as Rectangle and Text lack public C++ APIs. Is there a reason behind the avoidance of QQmlComponent?

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

      1 Reply Last reply
      0
      • B Offline
        B Offline
        bguivarch
        wrote on 6 Sept 2016, 06:46 last edited by
        #3

        Hello and thanks for your answer.
        The reason I want to avoid loading an existing QML file is because I want this kind of relationship: each instance of my C++ object will have its own instance of QML object. By doing so, I want all the QML properties to be linked to the C++ properties of the instance.

        I know that I can expose a C++ object into the QML context with:

        QQmlApplicationEngine engine;
        MyObject sc;
        engine.rootContext()->setContextProperty("myobject",&sc);
        

        And then in my Foo.qml file use it to access the Q_PROPERTY I have declared in the class MyObject:

        Rectangle{
           width:sc.width
        }
        

        But for me (and I may be wrong), doing this will expose a global "myobject" variable that will be used by every instances of Foo.qml that I will dynamically create with Qt.createQmlObject or Qt.createComponent. And I want a one-instance-to-one-instance system.

        I hope I made myself clear :/

        1 Reply Last reply
        0
        • J Offline
          J Offline
          jeremy_k
          wrote on 6 Sept 2016, 07:29 last edited by
          #4

          I think that I understand. For some nontrivial number of QML objects, the goal is to bind to a unique property whose value can be controlled from C++. SetContextProperty does indeed create a global variable that will have the same value for all items that reference it.

          It sounds like these C++ objects are sources for properties, but probably don't have visual properties.

          One option is to compose the visual portion in QML, with a QObject-derived, qmlRegisterType() registered object as the source for the C++ properties.

          MyItem.qml

          import org.examples 1.0
          Rectangle {
              CppObj { id: cppObj }
              Text { text: cppObj.text }
          }
          

          main.cpp

          class CppObj : public QObject {
              Q_OBJECT
              Q_PROPERTY(QString text ...)
          public:
              CppObj(QObject * parent = nullptr);
              ...
          } ;
          
          CppObj::CppObj(QObject *parent) : QObject(parent)
          {
              // register the object instance or otherwise initialize properties
          }
          
          int main()
          {
              ...
              qmlRegisterType<CppObj>("org.examples", 1, 0, "CppObj");
              // Now load the root document
              ...
          }
          

          If this works for the use case, QQmlParserStatus might be of interest.

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

          1 Reply Last reply
          0
          • B Offline
            B Offline
            bguivarch
            wrote on 6 Sept 2016, 07:58 last edited by
            #5

            Hello,
            Just to be sure, in your example, in which context do you dynamically create the QML component? In the C++ context or the QML context? Is that what you mean in the constructor?

            I will have a look at QQmlParserStatus, never used that class before so I may ask you some questions about it too.

            J 1 Reply Last reply 6 Sept 2016, 08:18
            0
            • B bguivarch
              6 Sept 2016, 07:58

              Hello,
              Just to be sure, in your example, in which context do you dynamically create the QML component? In the C++ context or the QML context? Is that what you mean in the constructor?

              I will have a look at QQmlParserStatus, never used that class before so I may ask you some questions about it too.

              J Offline
              J Offline
              jeremy_k
              wrote on 6 Sept 2016, 08:18 last edited by
              #6

              @bguivarch said in Dynamically create a whole new QML object from C++:

              Hello,
              Just to be sure, in your example, in which context do you dynamically create the QML component? In the C++ context or the QML context? Is that what you mean in the constructor?

              It doesn't matter. After the type registration, any use of MyItem will instantiate an instance of CppObj. The CppObj's parent is the MyItem instance, and will be destroyed when MyItem is.

              The comment in CppObj::CppObj() is a place holder for doing something based on the 1:1 QML to C++ object relationship previously mentioned. I wasn't able to come up with a better, concise example construct based on the problem description.

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

              1 Reply Last reply
              0
              • B Offline
                B Offline
                bguivarch
                wrote on 9 Sept 2016, 09:07 last edited by
                #7

                Ok thanks for your help.

                1 Reply Last reply
                0

                1/7

                5 Sept 2016, 09:30

                • Login

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