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. Creating and changing qml objects from c++
Forum Updated to NodeBB v4.3 + New Features

Creating and changing qml objects from c++

Scheduled Pinned Locked Moved Solved QML and Qt Quick
8 Posts 2 Posters 2.3k Views
  • 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.
  • SeDiS Offline
    SeDiS Offline
    SeDi
    wrote on last edited by
    #1

    Hi,
    I create a component in c++ and use it as a sourceComponent for a Loader in QML, but - though setProperty returns true - I can't see the properties set by c++.

    The loader approach here is kind of a necessity, because in the end, the object to be created will be a complex, nested structure of qml files (I want to display math formulas). Most of these qml elements have loaders themselves (again: later to be set by c++), here I use the simplest qml (like an end branch of the nested structure).

    I try it this way (shortened code):

    main.cpp:

    int main(int argc, char *argv[])
    {
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
        QGuiApplication app(argc, argv);
        QQmlApplicationEngine engine;
    
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
        if (engine.rootObjects().isEmpty())
            return -1;
    
        QObject *root = engine.rootObjects()[0]; // yet unused
    
       QQmlComponent* component = new QQmlComponent(&engine, QUrl(QStringLiteral("qrc:/ElementVariable.qml")));
        QQuickItem *item = qobject_cast<QQuickItem*>(component->create());
    
        qDebug()<< item->setProperty("text", "myNewText");  //returns true
        qDebug()<<item->setProperty("visible", true); //returns true
    
        engine.rootContext()->setContextProperty("EquationComponent", QVariant::fromValue<QQmlComponent*>(component));
     
        return app.exec();
    }
    

    main.qml:

    ApplicationWindow {
        visible: true
        width: 640
        height: 480
        Component {
            id: emptyComponent
            Item {
            }
        }
        Loader {
            objectName: "equationLoader"
            sourceComponent: typeof EquationComponent !== "undefined" ? EquationComponent : emptyComponent;
            width: childrenRect.width
            height: childrenRect.height
        }
    }
    

    ElementVariable.qml:

    import QtQuick 2.0
    
    Rectangle {
        property alias text: textItem.text
        width: childrenRect.width
        height: childrenRect.height
        Text {
            id: textItem
            width: implicitWidth + 10
            height: implicitHeight
            text: "textUnchanged"  // this I want to change
            verticalAlignment: Text.AlignVCenter
            horizontalAlignment: Text.AlignHCenter
        }
    }
    

    Result: I do see the element, but I don't see the text that is set in the main.cpp, I only see the Component's default text.

    Any ideas?

    1 Reply Last reply
    0
    • dheerendraD Offline
      dheerendraD Offline
      dheerendra
      Qt Champions 2022
      wrote on last edited by dheerendra
      #2

      @SeDi said in Creating and changing qml objects from c++:

      I can't see the properties set by c++.

      Where are you setting the properties in C++ which you would like see on QML ? Atleast I don't see that code here.

      Dheerendra
      @Community Service
      Certified Qt Specialist
      http://www.pthinks.com

      SeDiS 1 Reply Last reply
      0
      • dheerendraD dheerendra

        @SeDi said in Creating and changing qml objects from c++:

        I can't see the properties set by c++.

        Where are you setting the properties in C++ which you would like see on QML ? Atleast I don't see that code here.

        SeDiS Offline
        SeDiS Offline
        SeDi
        wrote on last edited by
        #3

        @dheerendra - thanks for your reply!

        I set it right before the end of the main.cpp. It is a bit "hidden" because I have prepended it with qDebug()<<

            qDebug()<< item->setProperty("text", "myNewText");  //returns true
            qDebug()<<item->setProperty("visible", true); //returns true
        
        1 Reply Last reply
        0
        • dheerendraD Offline
          dheerendraD Offline
          dheerendra
          Qt Champions 2022
          wrote on last edited by
          #4

          Here you are changing the properties of object called item. This object is not going to change your component.

          Dheerendra
          @Community Service
          Certified Qt Specialist
          http://www.pthinks.com

          SeDiS 1 Reply Last reply
          0
          • dheerendraD dheerendra

            Here you are changing the properties of object called item. This object is not going to change your component.

            SeDiS Offline
            SeDiS Offline
            SeDi
            wrote on last edited by
            #5

            @dheerendra - oh, I see. Thank you for your time and effort!

            I have changed

            engine.rootContext()->setContextProperty("EquationComponent", QVariant::fromValue<QQmlComponent*>(component));
            

            into

            engine.rootContext()->setContextProperty("EquationComponent", QVariant::fromValue<QQuickItem*>(item));
            

            but I get the error:
            "qrc:/main.qml:17:26: Unable to assign ElementVariable_QMLTYPE_2 to QQmlComponent"

            This seems understandable - it's called sourceComponent: after all.

            Having reverted the above idea (back to setting the component, not the item) I have also tried to set the properties on the component - doesn't work either:

                qDebug()<< component ->setProperty("text", "myNewText");  //returns false
                qDebug()<<component ->setProperty("visible", true); //returns false
            

            It appears that I might have a misconception about Components/Items and that I lack sufficient knowledge about the Loader QML element.

            • is a Component more like a template / a class?
            • is an Item its realisation, like an actual object?
            • How can I "force-feed" the Loader from c++ with a specific Object created from there?
            1 Reply Last reply
            0
            • dheerendraD Offline
              dheerendraD Offline
              dheerendra
              Qt Champions 2022
              wrote on last edited by
              #6

              Yes component is like class. Once done you can’t change. you can change properties of object. You can specify the properties while loading. You can check documentation for this.

              Dheerendra
              @Community Service
              Certified Qt Specialist
              http://www.pthinks.com

              1 Reply Last reply
              0
              • SeDiS Offline
                SeDiS Offline
                SeDi
                wrote on last edited by SeDi
                #7

                Thank you very much! That solved it. The creation process is being done automatically by the Loader in QML. It didn't make sense to make a second and unrelated "component->create()" in c++. I have to set the Component first and then get the Item from the Loader via property("item") afterwards.

                Here's the code involved:

                loader->setProperty("sourceComponent", QVariant::fromValue<QQmlComponent*>(component));
                QQuickItem* loaderItem = qvariant_cast<QQuickItem*>(loader->property("item"));
                loaderItem->setProperty("text", "myNewText");
                
                1 Reply Last reply
                0
                • dheerendraD Offline
                  dheerendraD Offline
                  dheerendra
                  Qt Champions 2022
                  wrote on last edited by
                  #8

                  NO need to set the property from C++ by getting item. You can do something like
                  Loader { sourceComponent: EquationComponent; text: "PthinkS" }

                  Dheerendra
                  @Community Service
                  Certified Qt Specialist
                  http://www.pthinks.com

                  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