-1

私たちのプロジェクトには、QML ソースの C++ 単体テストがあります。次のコードを使用して、コンポーネントを動的にロードしてさらに処理します

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。ただし、この https://doc.qt.io/qt-5/qquickview.html#details のようQQuickItemにロードしようとしています:QQuickView

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()このモジュールをRectangleitemに対して正しくロードQQmlApplicationEngineし、同じ item 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();
}
  • その後、別のエラーが発生します:

    QQmlComponent: コンポーネントの準備ができていません

呼び出されない場合engine->addImportPath()、クラッシュします

場所: [不明なファイル(0)]

呼び出し時のエラーengine->addImportPath()

正しくロードDialog( ) し、テストのために C++QQuickWindowでルートを取得する方法は? QQuickItem何か案は?ありがとう!

4

1 に答える 1