В нашем проекте у нас есть модульные тесты C++ для источников QML. Он использует следующий код для динамической загрузки компонента для дальнейшей обработки.
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();
}
}
Отлично работал для таких компонентов qml:
my.qml:
Rectangle {
...
}
Однако, когда я завернул компонент в Dialog
Dialog {
...
Rectangle {
...
}
}
он перестал работать:
Ошибка:
QQuickWidget
поддерживает загрузку только корневых объектов, производных отQQuickItem
.
Что ожидается, поскольку Dialog
является QQuickWindow
. Однако при попытке загрузить QQuickItem
через QQuickView
вот так 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();
}
Сбой с вышеуказанной ошибкой, а также. И загрузка через QQmlApplicationEngine
, как здесь 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();
}
вылетает с другой ошибкой:
QQmlApplicationEngine
не удалось загрузить компонент
QWARN :MyTest::myMethodTest()
модуль "mynamespace.mymodule
" не установлен
QWARN :MyTest::myMethodTest()
модуль "mynamespace.mymodule
" не установлен
...
Почему view->setSource()
правильно загружает эти модули для элемента Rectangle
, а QQmlApplicationEngine
не работает для того же исходного кода qml элемента, но заключенного в Dialog
?
Примечание. эти модули написаны на C++ и нормально загружаются с
view->setSource()
.
Если я попытаюсь использовать и загрузить через QQmlComponent
, как указано в документации: 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();
}
- затем другая ошибка:
#P14#
если engine->addImportPath()
не вызывается, и сбой с
Местонахождение: [Неизвестный файл(0)]
ошибка при вызове engine->addImportPath()
.
Как правильно загрузить Dialog
(QQuickWindow
) и получить root QQuickItem
в C++ для тестирования? Любые идеи? Спасибо!