web-dev-qa-db-ja.com

QQmlApplicationEngineの使用中にC ++からWindowオブジェクトプロパティにアクセスするにはどうすればよいですか?

私はGUI作成のためにQtQuickを学ぼうとしましたが、テストプログラムのC++部分からQMLオブジェクトと対話する方法を理解するのに苦労していました。

これが私の簡単なQMLファイルです。

import QtQuick 2.2
import QtQuick.Window 2.1

Window {
    id: mainWindow
    visible: true
    width: 800
    height: 800
    color: "#FFFF0000"

    MouseArea {
        anchors.fill: parent
        onClicked: Qt.quit()
    }

    Rectangle {
        id: testRect
        width: 100
        height: 100
        anchors.centerIn: parent
        color: "#FF0000FF"
    }
}

付属の基本的なC++ファイルは次のとおりです(QtCreatorによって自動生成されます)。

#include <QGuiApplication>
#include <QQmlApplicationEngine>

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:///main.qml")));

    return app.exec();
}

私の問題は、アイデアがない私の「ウィンドウ」QMLオブジェクトにアクセスする方法があり、その結果、私は何も変更できないことですそのプロパティまたはその子のプロパティの! QtQuickドキュメントのこの部分では、C++コード内からQMLオブジェクトにアクセスする2つの方法を示していますが、どちらもこの「QQmlApplicationEngine」ロードスキームには適用されないようです。また、「QApplicationViewer」や、しかし公式ドキュメントでそれらを見つけることができないようです。

QtQuickには本当にイライラしています。 QMLの「シンプルさ」は、C++とQMLの間の矛盾するドキュメントと複雑なインターフェースの海で失われているようです。とにかく、QQmlApplicationEngineメソッドを使用しながらQMLオブジェクトにアクセスすることはできますか? 「QuickView」を使用してみましたが、Window QMLオブジェクトではうまく動作しないようです。 QQmlApplicationEngineは、単一ファイル内のQML専用アプリケーションにのみ有用ですか?これまでのところ、私が読んだすべてのドキュメントとチュートリアルは、何か異なることを示しています。

どんな助けや明確化も大歓迎です。 理想的には、C++コードを介してQMLオブジェクト(「mainWindow」、「testRect」、および他のファイル内の他のオブジェクトなど)にアクセスして変更する方法を知りたい

39
MrKatSwordfish

私のコメントを適切な答えに変える:これは通常2つの方法で行われます。

  • QQuickViewまたは直接QQmlApplicationEngineを直接使用する場合、ビューからQMLシーンのルートオブジェクトを取得します。

  • ルートオブジェクトの場合、この次の手順は省略できますが、一般に「qmlオブジェクト」の場合は、 objectNameプロパティ を設定する必要があり、次の方法で子を見つけることができます。

QList QObject :: findChildren(const QString&name = QString()、Qt :: FindChildOptions options = Qt :: FindChildrenRecursively)const

C++側

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QDebug>

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:///main.qml")));

    // Step 1: get access to the root object
    QObject *rootObject = engine.rootObjects().first();
    QObject *qmlObject = rootObject->findChild<QObject*>("mainWindow");

    // Step 2a: set or get the desired property value for the root object
    rootObject->setProperty("visible", true);
    qDebug() << rootObject->property("visible");

    // Step 2b: set or get the desired property value for any qml object
    qmlObject->setProperty("visible", true);
    qDebug() << qmlObject->property("visible");

    return app.exec();
}

プロパティセットのドキュメントを参照し、公式ドキュメントを入手してください。

bool QObject :: setProperty(const char * name、const QVariant&value)

そして

QVariant QObject :: property(const char * name)const

いいですね、C++側で多かれ少なかれ完了です。

QML側

また、次のようにルートアイテム以外にもアクセスする場合は、qmlオブジェクトのobjectNameプロパティを設定する必要があります。

import QtQuick 2.2
import QtQuick.Window 2.1

Window {
    id: mainWindow
    objectName: "mainWindow"
    ...
}

これは、どのQMLオブジェクトでも同様に実行できます。ここでのキーは「objectName」です。 C++側がルートオブジェクトを直接取得するため、ルートオブジェクトについては省略できますが、質問でQMLオブジェクトを参照しているため、一般的に解決したいと思います。子を含むQMLオブジェクトに対して同じことを行うには、 objectNameプロパティ を使用する必要があります。

47
lpapp