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. [SOLVED] Injecting Qml Objects created in c++ into existing Qml Elements
Forum Updated to NodeBB v4.3 + New Features

[SOLVED] Injecting Qml Objects created in c++ into existing Qml Elements

Scheduled Pinned Locked Moved QML and Qt Quick
qml
10 Posts 2 Posters 3.1k Views 2 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.
  • K Offline
    K Offline
    kuschky
    wrote on 3 Mar 2015, 21:21 last edited by p3c0 3 Jul 2015, 05:52
    #1

    Hello, I created a C++ app with a QQuickView like this

    QQuickView view;
    view.setSource(QUrl::fromLocalFile("MainItem.qml"));
    view.show();
    

    MainItem.qml

    import QtQuick 2.3
    
    Item  {
        width: 400
        height: 400
        
        Item  {
            x: 0
            y: 0
            width: 300
            height: 300
            objectName:  "subMainItem"
            
            ...
        }
        
        ...
    
    }
    

    and I got my MainItem displayed

    Then I load another Component from a Qml file

    QQmlComponent component(&engine,
    QUrl::fromLocalFile("ChildItem.qml"));
    QObject *object = component.create();
    

    ChildItem.qml

    import QtQuick 2.3
    
    Item  {
        width: 100
        height: 100
    
        ...
    }
    

    My question is now how can I inject the childItem into the MainItems subMainItem element? I already tried different variations with setting parent properties etc. but I don't get the child to become visible. Does somebody have a simple example? I'm working with Qt 5.4.1 and QtQuick 2.3

    Thanks for your help

    Edited: Use Markdown syntax rules - p3c0

    K 1 Reply Last reply 6 Mar 2015, 08:19
    0
    • P Offline
      P Offline
      p3c0
      Moderators
      wrote on 4 Mar 2015, 05:00 last edited by
      #2

      Hi,

      Did you "setParentItem":http://doc.qt.io/qt-5/qquickitem.html#parent-prop to ChildItem ?

      157

      1 Reply Last reply
      0
      • K kuschky
        3 Mar 2015, 21:21

        Hello, I created a C++ app with a QQuickView like this

        QQuickView view;
        view.setSource(QUrl::fromLocalFile("MainItem.qml"));
        view.show();
        

        MainItem.qml

        import QtQuick 2.3
        
        Item  {
            width: 400
            height: 400
            
            Item  {
                x: 0
                y: 0
                width: 300
                height: 300
                objectName:  "subMainItem"
                
                ...
            }
            
            ...
        
        }
        

        and I got my MainItem displayed

        Then I load another Component from a Qml file

        QQmlComponent component(&engine,
        QUrl::fromLocalFile("ChildItem.qml"));
        QObject *object = component.create();
        

        ChildItem.qml

        import QtQuick 2.3
        
        Item  {
            width: 100
            height: 100
        
            ...
        }
        

        My question is now how can I inject the childItem into the MainItems subMainItem element? I already tried different variations with setting parent properties etc. but I don't get the child to become visible. Does somebody have a simple example? I'm working with Qt 5.4.1 and QtQuick 2.3

        Thanks for your help

        Edited: Use Markdown syntax rules - p3c0

        K Offline
        K Offline
        kuschky
        wrote on 6 Mar 2015, 08:19 last edited by p3c0 3 Jun 2015, 11:19
        #3

        Hello, thanks for the hint with the setParentItem method. But unfortunately it does not solve the problem

        I'm still trying to figure out was going wrong. I did wrote a very simple program (going back to Qt 5.3.2) which opens a DeclarativeView from an Qml file with an Rectangle with red background inside - This red one is displayed in the view.

        Then I create a QDeclarativeComponent from another Qml file which contains another Rectangle with yellow Background. I created an Object from it and call the setParentItem to connect it as a child to the root DeclarativeItem object (the red one).

        Because my Qt is not compiled with debug option objectdump does not work for my and I wrote some own functions that prints out the parent/child tree including the attributes of the children. In the console output you can see that the yellow Item is a child of the red one and the attributes for x,y,z, width, height and visibility looking o.k.

        But Item with the yellow Rectangle is not shown on the screen

        I would be glad if there is somebody who can help me to solve the issue. I added the whole project if somebody want to try it. The project was build with Qt 5.3.2 on a Linux x86 32 bit environment.

        PS: The code formating of the new forum it's a mess. The old format does not work anymore and the new one is some kind of random formating.

        main.cpp

        #include "mainwindow.h"
        #include <QApplication>
        #include <QtDeclarative>
        #include <QDeclarativeComponent>
        #include <QDeclarativeProperty>
        
        void printComponentErrors(QDeclarativeComponent* pComponent);
        quint32 printItemCildren(QDeclarativeItem* pParentItem, quint32 level);
        quint32 printItemAttributes(QDeclarativeItem* pItem, quint32 level);
        
        
        int main(int argc, char *argv[])
        {
            QApplication a(argc, argv);
            MainWindow w;
        
            QDeclarativeView* pView = new QDeclarativeView();
            pView->resize(400,400);
        
            w.setCentralWidget(pView);
        
            QUrl myUrl("red.qml");
            pView->setSource(myUrl);
        
            QDeclarativeView::Status viewerStatus =  pView->status();
        
            if (viewerStatus != QDeclarativeView::Ready )
            {
                qDebug() << "Could not open qml file";
            }
            else
            {
                bool success = false;
        
                QDeclarativeComponent component(pView->engine(),QUrl("yellow.qml"));
        
                QGraphicsObject* pRoot = pView->rootObject();
        
                if (pRoot != NULL)
                {
                    QObject* pObject = component.beginCreate(QDeclarativeEngine::contextForObject(pRoot));
        
                    QDeclarativeItem* pNewItem = qobject_cast<QDeclarativeItem*>(pObject );
        
                    if (pNewItem == NULL)
                    {
        
                        QDeclarativeComponent::Status status = component.status();
        
                        if ( status != QDeclarativeComponent::Ready )
                        {
        
                            printComponentErrors(&component);
                        }
        
                        component.completeCreate();
                    }
                    else
                    {
                        QDeclarativeItem* pRootItem = qobject_cast<QDeclarativeItem*>(pRoot);
        
                        if (pRootItem != NULL)
                        {
                            pNewItem->setFlag(QGraphicsItem::ItemHasNoContents, false);
                            pNewItem->setParentItem(pRootItem);
        
                            QDeclarativeEngine::setObjectOwnership(pNewItem, QDeclarativeEngine::CppOwnership);
        
                            success = QDeclarativeProperty::write(pNewItem, "objectName", "yellowBox");
                            success = QDeclarativeProperty::write(pNewItem, "visible", true);
                            success = QDeclarativeProperty::write(pNewItem, "z", 20);
        
                            pNewItem->deleteLater();
                        }
        
                        component.completeCreate();
        
                        success = QDeclarativeProperty(pNewItem, "visible").write(false);
                        success = QDeclarativeProperty(pNewItem, "visible").write(true);
                    }
        
                    QDeclarativeItem* pRootItem = qobject_cast<QDeclarativeItem*>(pRoot );
                    if (pRootItem != NULL)
                    {
                        printItemCildren(pRootItem, 1);
                    }
                }
        
        
            }
        
            w.resize(400,400);
        
            w.show();
        
            return a.exec();
        }
        
        void printComponentErrors(QDeclarativeComponent* pComponent)
        {
            QList<QDeclarativeError> componentErrors =  pComponent->errors();
        
            quint16 errorNo = 1;
            QList<QDeclarativeError>::Iterator errorIter = componentErrors.begin();
        
            while (errorIter != componentErrors.end())
            {
                QDeclarativeError pQmlError = *errorIter;
        
                qDebug() << "QmlComponent error" << errorNo << ": " << pQmlError.toString();
        
                errorIter++;
            }
        
        }
        
        quint32 printItemCildren(QDeclarativeItem* pParentItem, quint32 level)
        {
            QString levelString;
        
            quint32 itemsFound = 0;
        
            QString parentName = pParentItem->objectName();
        
            QList<QGraphicsItem*> childItems =  pParentItem->childItems();
        
            QList<QGraphicsItem*>::Iterator childItemIter = childItems.begin();
        
            for (quint32 i = 0; i< level; i++)
            {
                levelString = levelString + '+';
            }
        
            printItemAttributes(pParentItem, level );
        
            while (childItemIter != childItems.end())
            {
                itemsFound ++;
        
                QDeclarativeItem* pChildItem = qobject_cast<QDeclarativeItem*>(*childItemIter);
        
                QString childName = pChildItem->objectName();
        
                qDebug() << levelString << " " << parentName << " has child named " << childName;
        
                itemsFound += printItemCildren(pChildItem, level + 1);
        
                childItemIter++;
            }
        
            return itemsFound;
        }
        
        quint32 printItemAttributes(QDeclarativeItem* pItem, quint32 level)
        {
            quint32 attributesFound = 0;
        
            if (pItem != NULL)
            {
                QString levelString;
        
                QString itemName = pItem->objectName();
        
                for (quint32 i = 0; i< level; i++)
                {
                    levelString = levelString + '@';
                }
        
                const QMetaObject *metaobject = pItem->metaObject();
                int count = metaobject->propertyCount();
        
                for (int i=0; i<count; ++i) {
                    QMetaProperty metaproperty = metaobject->property(i);
                    const char *name = metaproperty.name();
                    QVariant value = pItem->property(name);
                    qDebug() << levelString << " " << itemName << " has property named " << name << " with value " << value;
                }
        
            }
        
            return attributesFound;
        }
        

        mainwindow.cpp

        #include "mainwindow.h"
        #include "ui_mainwindow.h"
        
        MainWindow::MainWindow(QWidget *parent) :
            QMainWindow(parent),
            ui(new Ui::MainWindow)
        {
            ui->setupUi(this);
        }
        
        MainWindow::~MainWindow()
        {
            delete ui;
        }
        

        mainwindow.h

        #ifndef MAINWINDOW_H
        #define MAINWINDOW_H
        
        #include <QMainWindow>
        
        namespace Ui {
        class MainWindow;
        }
        
        class MainWindow : public QMainWindow
        {
            Q_OBJECT
        
        public:
            explicit MainWindow(QWidget *parent = 0);
            ~MainWindow();
        
        private:
            Ui::MainWindow *ui;
        };
        
        #endif // MAINWINDOW_H
        

        red.qml

        import QtQuick 1.1
        
        Rectangle {
            objectName: "redbox"
            width: 400
            height: 400
            color: "red"
            visible: true
        
            Text {
                text: "some text in red"
                anchors.centerIn: parent
            }
        }
        

        yellow.qml

        import QtQuick 1.1
        
        Rectangle {
            objectName: "yellowBox"
            x: 0
            y: 0
            width: 20
            height: 20
            color: "yellow"
            visible: true
        
            Text {
                text: "some text in yellow"
                anchors.centerIn: parent
            }
        }
        

        .pro file

        #-------------------------------------------------
        #
        # Project created by QtCreator 2015-03-05T18:59:38
        #
        #-------------------------------------------------
        
        QT       += core gui
        
        greaterThan(QT_MAJOR_VERSION, 4): QT += widgets declarative
        
        TARGET = QmlTest
        TEMPLATE = app
        SOURCES += main.cpp\
                mainwindow.cpp
        
        HEADERS  += mainwindow.h
        
        FORMS    += mainwindow.ui
        
        DISTFILES += \
            red.qml \
            yellow.qml
        

        Edited: Use Markdown syntax rules - p3c0

        1 Reply Last reply
        0
        • P Offline
          P Offline
          p3c0
          Moderators
          wrote on 6 Mar 2015, 08:44 last edited by p3c0 3 Jun 2015, 08:44
          #4

          Are you sure you are using Qt 5.3 ? QDeclarative* classes are a part of Qt4.x and have been deprecated in Qt5.
          Have a look at this porting guide.

          157

          1 Reply Last reply
          0
          • P Offline
            P Offline
            p3c0
            Moderators
            wrote on 6 Mar 2015, 08:53 last edited by p3c0 3 Jun 2015, 08:54
            #5

            Try the following example:

            //MyItem.qml
            import QtQuick 2.4
            
            Item {
                width: 200
                height: 200
            
                Rectangle {
                    objectName: "subChildItem"
                    width: 100
                    height: 100
                    color: "red"
                }
            }
            
            //main.cpp
            QQuickView view;
            view.setSource(QStringLiteral("qrc:/MyItem.qml"));
            view.show();
            QQmlComponent component(view.engine());
            component.setData("import QtQuick 2.0\nText { text: \"Hello\"; anchors.centerIn: parent }", QUrl());
            QQuickItem *obj = qobject_cast<QQuickItem*>(component.create());
            QQuickItem *item = view.rootObject()->findChild<QQuickItem *>("subChildItem");
            obj->setParentItem(item);
            
            

            Try commenting setParentItem to see the difference.

            157

            1 Reply Last reply
            0
            • K Offline
              K Offline
              kuschky
              wrote on 6 Mar 2015, 09:54 last edited by kuschky 3 Jun 2015, 09:56
              #6

              Thanks for your answer. I tried and it and it worked with QtQuick 2.3. When I comment the setParentItem method call the inserted text doesn't appear like expected.

              But I can't use QtQuick >= 2 because the device for which I developing the application does not support OpenGL. That's the reason I'm using QtQuick 1.1. That's also the reason for using the Declarative instead the new Qml interface. Because the new QQml and QQuick interface seems to not supporting QtQuick 1.1.

              So I'm forced from the target hardware to use QtQuick 1.1. Do you have any idea how to get it running with QQuick 1.1 and the Declarative interface?

              1 Reply Last reply
              0
              • P Offline
                P Offline
                p3c0
                Moderators
                wrote on 6 Mar 2015, 11:26 last edited by p3c0 3 Jun 2015, 11:34
                #7

                Ok. Sorry, I'm not sure about the QDeclarative* stuff. Any errors printed in printComponentErrors ?
                Also the new forum's editor follows markdown markup language and so it has its own syntax rules. For eg. to post code I have encapsulated it inside ` (backtick symbol). I have also edited your earlier posts.
                Edit: Seems single backtick is enough too.

                157

                K 1 Reply Last reply 6 Mar 2015, 11:43
                1
                • P p3c0
                  6 Mar 2015, 11:26

                  Ok. Sorry, I'm not sure about the QDeclarative* stuff. Any errors printed in printComponentErrors ?
                  Also the new forum's editor follows markdown markup language and so it has its own syntax rules. For eg. to post code I have encapsulated it inside ` (backtick symbol). I have also edited your earlier posts.
                  Edit: Seems single backtick is enough too.

                  K Offline
                  K Offline
                  kuschky
                  wrote on 6 Mar 2015, 11:43 last edited by kuschky 3 Jun 2015, 11:53
                  #8

                  Thanks for the code format hint and editing

                  Component creations were succesful .No, no component errors printed and the properties of the child and root Items printed by the attached functions looking o.k. for me but the child gots not displayed. Any other ideas?

                  1 Reply Last reply
                  0
                  • P Offline
                    P Offline
                    p3c0
                    Moderators
                    wrote on 6 Mar 2015, 11:54 last edited by
                    #9

                    pNewItem->deleteLater();
                    This could be the error. You are deleting the object as soon as you create them.

                    157

                    K 1 Reply Last reply 6 Mar 2015, 13:26
                    1
                    • P p3c0
                      6 Mar 2015, 11:54

                      pNewItem->deleteLater();
                      This could be the error. You are deleting the object as soon as you create them.

                      K Offline
                      K Offline
                      kuschky
                      wrote on 6 Mar 2015, 13:26 last edited by kuschky 3 Jun 2015, 13:27
                      #10

                      Cool! If I remove the deleteLater it works :-) I did find an example somewhere in a forum thread and adopted the usage of deleteLater without knowing exactly what it does. In the thread they just say that it's neccessary to clean up all objects later. Know I read the docs and it makes sense what you say.

                      Thank you very much for your help. You saved my day

                      1 Reply Last reply
                      0

                      1/10

                      3 Mar 2015, 21:21

                      • Login

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