Hello,
I'm struggling with dynamic loading of *.qml files. Although my real application is way bigger I have managed to reduce the problem to following code:
(1) Single c++ application loading main.qml and then loading WindControlItem.qml
/*
* main.cpp
*/
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickItem>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.
load(QUrl(QStringLiteral
("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
// Root object for finding QML Items by their objectName
QObject* root
= engine.
rootObjects()[0];
assert(root != nullptr);
// The QML Item to which we want to inject our QML-Item-loaded-from-file
QQuickItem* centralPane = qobject_cast<QQuickItem*>(root->findChild<QObject*>("centralPane"));
assert(centralPane != nullptr);
// Load the QML file to a component
QString qml_path
= "WeatherCtrlItem.qml";
QQmlComponent comp
(&engine,
QUrl::fromLocalFile(qml_path
));
// Create an instance of the component
assert(obj != nullptr);
// Up-cast it to a QQuickItem
QQuickItem *item = qobject_cast<QQuickItem*>(obj);
assert(item != nullptr);
// Born C++, die QML
engine.setObjectOwnership(item, QQmlEngine::JavaScriptOwnership);
// Set QObject-parent to the central pane
item->setParent(centralPane);
// Set Visual-parent to the central pane
item->setParentItem(centralPane);
return app.exec();
}
/*
* main.cpp
*/
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickItem>
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;
// Root object for finding QML Items by their objectName
QObject* root = engine.rootObjects()[0];
assert(root != nullptr);
// The QML Item to which we want to inject our QML-Item-loaded-from-file
QQuickItem* centralPane = qobject_cast<QQuickItem*>(root->findChild<QObject*>("centralPane"));
assert(centralPane != nullptr);
// Load the QML file to a component
QString qml_path = "WeatherCtrlItem.qml";
QQmlComponent comp(&engine, QUrl::fromLocalFile(qml_path));
// Create an instance of the component
QObject* obj = comp.create();
assert(obj != nullptr);
// Up-cast it to a QQuickItem
QQuickItem *item = qobject_cast<QQuickItem*>(obj);
assert(item != nullptr);
// Born C++, die QML
engine.setObjectOwnership(item, QQmlEngine::JavaScriptOwnership);
// Set QObject-parent to the central pane
item->setParent(centralPane);
// Set Visual-parent to the central pane
item->setParentItem(centralPane);
return app.exec();
}
To copy to clipboard, switch view to plain text mode
(2) Content of main.qml
/*
* main.qml
*/
import QtQuick 2.10
import QtQuick.Controls 1.4
ApplicationWindow {
id: root
visible: true
width: 800
height: 600
menuBar: MenuBar {
Menu {
title: "File"
MenuItem {
text: "Exit"
onTriggered: Qt.exit(0)
}
} // Menu
} // MenuBar
Rectangle {
anchors.left: parent.left
width: (parent.width * 0.2)
height: parent.height
}
// I want this item to eventually become a parent of another dynamically loaded
// item -- that's why I give it an objectName.
Rectangle {
objectName: "centralPane"
width: parent.width * 0.6
height: parent.height
anchors.horizontalCenter: parent.horizontalCenter
}
Rectangle {
width: (parent.width * 0.2)
height: parent.height
anchors.right: parent.right
}
} // ApplicationWindow
/*
* main.qml
*/
import QtQuick 2.10
import QtQuick.Controls 1.4
ApplicationWindow {
id: root
visible: true
width: 800
height: 600
menuBar: MenuBar {
Menu {
title: "File"
MenuItem {
text: "Exit"
onTriggered: Qt.exit(0)
}
} // Menu
} // MenuBar
Rectangle {
anchors.left: parent.left
width: (parent.width * 0.2)
height: parent.height
}
// I want this item to eventually become a parent of another dynamically loaded
// item -- that's why I give it an objectName.
Rectangle {
objectName: "centralPane"
width: parent.width * 0.6
height: parent.height
anchors.horizontalCenter: parent.horizontalCenter
}
Rectangle {
width: (parent.width * 0.2)
height: parent.height
anchors.right: parent.right
}
} // ApplicationWindow
To copy to clipboard, switch view to plain text mode
(3) Content of WindControlItem.qml
/*
* WindControlItem.qml
*/
import QtQuick 2.10
import QtQuick.Controls 1.4
Rectangle {
id: recRoot
color: "#778899"
anchors.fill: parent
GroupBox {
id: gpbLayers
title: "Wind layers"
anchors.fill: parent
Grid {
id: grdFields
anchors.fill: parent
columns: 2
Text {
text: "speed"
}
TextField {
id: fieldSpeed
placeholderText: "meters/sec"
}
Text {
text: "direction"
}
TextField {
id: fieldDir
placeholderText: "degrees"
}
Button{
text: "Add layer"
}
} // Grid
} // GroupBox
} // Item root
/*
* WindControlItem.qml
*/
import QtQuick 2.10
import QtQuick.Controls 1.4
Rectangle {
id: recRoot
color: "#778899"
anchors.fill: parent
GroupBox {
id: gpbLayers
title: "Wind layers"
anchors.fill: parent
Grid {
id: grdFields
anchors.fill: parent
columns: 2
Text {
text: "speed"
}
TextField {
id: fieldSpeed
placeholderText: "meters/sec"
}
Text {
text: "direction"
}
TextField {
id: fieldDir
placeholderText: "degrees"
}
Button{
text: "Add layer"
}
} // Grid
} // GroupBox
} // Item root
To copy to clipboard, switch view to plain text mode
When I start the application the GUI displays correctly. The problem is that after I close the ApplicationWindow lots of warnings are printed to the output:
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/GroupBox.qml:184: ReferenceError: parent is not defined
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/GroupBox.qml:204: ReferenceError: parent is not defined
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/GroupBox.qml:205: ReferenceError: parent is not defined
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/GroupBox.qml:206: ReferenceError: parent is not defined
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/GroupBox.qml:216: ReferenceError: parent is not defined
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/Private/Control.qml:90: ReferenceError: parent is not defined
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/Private/AbstractCheckable.qml:123: ReferenceError: parent is not defined
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/Private/Control.qml:90: ReferenceError: parent is not defined
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/TextField.qml:656: ReferenceError: parent is not defined
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/Private/TextInputWithHandles.qml:104: ReferenceError: parent is not defined
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/Private/TextInputWithHandles.qml:131: ReferenceError: parent is not defined
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/Private/Control.qml:90: ReferenceError: parent is not defined
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/TextField.qml:656: ReferenceError: parent is not defined
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/Private/TextInputWithHandles.qml:104: ReferenceError: parent is not defined
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/Private/TextInputWithHandles.qml:131: ReferenceError: parent is not defined
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/Private/Control.qml:90: ReferenceError: parent is not defined
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/Private/BasicButton.qml:194: ReferenceError: parent is not defined
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/GroupBox.qml:184: ReferenceError: parent is not defined
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/GroupBox.qml:204: ReferenceError: parent is not defined
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/GroupBox.qml:205: ReferenceError: parent is not defined
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/GroupBox.qml:206: ReferenceError: parent is not defined
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/GroupBox.qml:216: ReferenceError: parent is not defined
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/Private/Control.qml:90: ReferenceError: parent is not defined
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/Private/AbstractCheckable.qml:123: ReferenceError: parent is not defined
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/Private/Control.qml:90: ReferenceError: parent is not defined
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/TextField.qml:656: ReferenceError: parent is not defined
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/Private/TextInputWithHandles.qml:104: ReferenceError: parent is not defined
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/Private/TextInputWithHandles.qml:131: ReferenceError: parent is not defined
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/Private/Control.qml:90: ReferenceError: parent is not defined
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/TextField.qml:656: ReferenceError: parent is not defined
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/Private/TextInputWithHandles.qml:104: ReferenceError: parent is not defined
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/Private/TextInputWithHandles.qml:131: ReferenceError: parent is not defined
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/Private/Control.qml:90: ReferenceError: parent is not defined
file:///C:/tools/Qt/5.12.0/msvc2017/qml/QtQuick/Controls/Private/BasicButton.qml:194: ReferenceError: parent is not defined
To copy to clipboard, switch view to plain text mode
I have tried to debug the code with both Qt 5.11.3 and Qt 5.12.0 but the resulting behavior is identical.
Finally my questions:
(1) Am I using correct approach for dynamic loading of Items defined in *.QML file?
(2) What could be the cause for the reference errors?
Than you for your answers!
Bookmarks