In our project we have C++ unit tests for QML sources. It uses following code to load component dynamically for further processing
class MyTest {
...
QScopedPointer<QQuickWidget> quickWidget;
QQuickItem* root = nullptr;
void setQmlSource(const QString& source)
{
quickWidget.reset(new QQuickWidget);
quickWidget->rootContext()->engine()->addImportPath("qrc:/qml");
quickWidget->setSource(QUrl::fromUserInput(source));
root = quickWidget->rootObject();
}
}
Worked fine for qml components like this:
my.qml:
Rectangle {
...
}
However when I wrapped component into Dialog
Dialog {
...
Rectangle {
...
}
}
it stopped to work:
Error:
QQuickWidgetonly supports loading of root objects that derive fromQQuickItem.
Which is expected as Dialog is a QQuickWindow. However trying to load QQuickItem via QQuickView like this https://doc.qt.io/qt-5/qquickview.html#details:
void MyTest::setQmlWindow(const QString& source)
{
QQuickView *view = new QQuickView;
view->rootContext()->engine()->addImportPath("qrc:/qml");
view->setSource(QUrl::fromUserInput(source));
root = view->rootObject();
}
Fails with above error as well. And loading via QQmlApplicationEngine like here https://stackoverflow.com/a/23936741/630169:
void MyTest::setQmlWindow(const QString& source)
{
engine = new QQmlApplicationEngine;
//engine->addImportPath("qrc:/qml");
engine->load(QUrl::fromUserInput(source));
QObject *myObject = engine->rootObjects().first();;
QQuickWindow *window = qobject_cast<QQuickWindow*>(myObject);
root = window->contentItem();
}
fails with another error:
QQmlApplicationEnginefailed to load component
QWARN :MyTest::myMethodTest()module "mynamespace.mymodule" is not installed
QWARN :MyTest::myMethodTest()module "mynamespace.mymodule" is not installed
...
Why view->setSource() loads this modules correctly for Rectangle item and QQmlApplicationEngine fails to do for the same item qml source but wrapped into the Dialog?
Note: these modules are C++ and loads fine with
view->setSource().
If I try to use and load via QQmlComponent like mentioned in documentation: https://doc.qt.io/qt-5/qqmlcomponent.html#details:
void MyTest::setQmlWindow(const QString& source)
{
engine = new QQmlApplicationEngine;
//engine->addImportPath("qrc:/qml");
QQmlComponent *component = new QQmlComponent(engine, QUrl::fromUserInput(source));
component->loadUrl(QUrl::fromUserInput(source));
QQuickWindow *window = qobject_cast<QQuickWindow*>(component->create());
root = window->contentItem();
}
- then have another error:
QQmlComponent: Component is not ready
if engine->addImportPath() is not called, and crash with
Loc: [Unknown file(0)]
error when engine->addImportPath() is called.
How to correctly load Dialog (QQuickWindow) and get it root QQuickItem in C++ for testing? Any ideas? Thanks!