QML Context lost when QML component is created from C++
-
Hello,
I have a simple C++ QQuickItem component that instantiates a QQmlComponent.
But within the instantiated QQmlComponent, the ids of other QML components are not known anymore (see detailed example below)
Apparently, the context is lost.The resulting log shows
qrc:/main.qml:35: ReferenceError: textId is not defined qml: Text(not delegate)=Hello WorldIs this something I can fix? Or is this 'logical'/'explainable' somehow?
The example code below illustrates the problem and consists of
- main.cpp
- MyQuickComponent.h
- MyQuickComponent.cpp
- main.qml
Thanks in advance,
Marc
main.cpp#include <QGuiApplication> #include <QQmlApplicationEngine> #include "myquickcomponent.h" QQmlApplicationEngine *engine; int main(int argc, char *argv[]) { qmlRegisterType<MyQuickComponent>("Mine", 1, 0, "MyQuickComponent"); QGuiApplication app(argc, argv); engine = new QQmlApplicationEngine(); engine->load(QUrl(QStringLiteral("qrc:/main.qml"))); return app.exec(); }MyQuickComponent.h
#ifndef MYQUICKCOMPONENT_H #define MYQUICKCOMPONENT_H #include <QQuickPaintedItem> #include <QPainter> class MyQuickComponent : public QQuickPaintedItem { Q_OBJECT Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged) public: MyQuickComponent(QQuickItem *parent = 0); void paint(QPainter *painter); QQmlComponent *delegate() const { return m_delegate; } void setDelegate(QQmlComponent *delegate); Q_SIGNALS: void delegateChanged(); private: QQmlComponent *m_delegate; }; #endif // MYQUICKCOMPONENT_HMyQuickComponent.cpp
#include <QQmlApplicationEngine> #include <QQmlContext> #include "myquickcomponent.h" MyQuickComponent::MyQuickComponent(QQuickItem *parent) : QQuickPaintedItem(parent), m_delegate(NULL) { } void MyQuickComponent::paint(QPainter *painter) { } extern QQmlApplicationEngine *engine; void MyQuickComponent::setDelegate(QQmlComponent *delegate) { if (delegate != m_delegate) { m_delegate = delegate; emit delegateChanged(); } //create object QQmlContext *context = new QQmlContext(engine->rootContext()); context->setContextObject(this); QQuickItem *object = qobject_cast<QQuickItem*>(m_delegate->create(context)); //QQuickItem *object = qobject_cast<QQuickItem*>(m_delegate->beginCreate(engine->rootContext())); QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership); object->setParentItem(this); object->setParent(this); object->setProperty("color", "red"); object->setProperty("y", 200); //m_delegate->completeCreate(); }And finally main.qml
import QtQuick 2.5 import QtQuick.Window 2.2 import Mine 1.0 Window { visible: true width:600 height: 600 Text { id: textId text: qsTr("Hello World") anchors.centerIn: parent } Rectangle { width:100 height:100 id: notdelegate //here I can access textId Component.onCompleted: console.log("Text(not delegate)="+textId.text) color: 'green' } //MyQuickComponent is a C++ QQuickItem that creates the delegate component MyQuickComponent { width:parent.width height: parent.width delegate: Rectangle { width:100 height:100 id: delegate //here I can't access textId !! Component.onCompleted: console.log("Text(delegate)="+textId.text) color: 'green' } } } -
Context actually exist and is not lost. Issue is getting from m_delegate.create(...) call. I don't know why. May be it failed to access the textId due some bug. I verified all the contexts, objects etc. Everything looks fine.
-
Apparently, it was sufficient to replace the line below in MyQuickComponent.cpp
QQmlContext *context = new QQmlContext(engine->rootContext());with
QQmlContext *context = m_delegate->creationContext();Note: how can I mark this question as fixed/solved?
-
Apparently, it was sufficient to replace the line below in MyQuickComponent.cpp
QQmlContext *context = new QQmlContext(engine->rootContext());with
QQmlContext *context = m_delegate->creationContext();Note: how can I mark this question as fixed/solved?
@MarcVanDaele Thanks for sharing the solution.
how can I mark this question as fixed/solved?
Under
Topic Toolscombobox there's an option as "Mark as Solved". I have marked it now.