C++からQMLへの状態の公開

あるコンポーネント内のすべてのQML要素、モジュール内のすべてのQML要素、 あるいはQML要素全体に対して、C++からいくつかのプロパティを公開したい場 合がよくあります。シングルトンを導入したり、選択したコンポーネントのルートオブジェクトに プロパティを追加したりすることで、これを実現することができます。

シングルトンの使用

モジュール内の全要素、あるいは全体の全要素に対して、いくつかのグローバルプロパティを公開したい場合、C++でシングルトンを定義することができます。これを行うには、QML_ELEMENT またはQML_NAMED_ELEMENT マクロとQML_SINGLETON マクロを、Q_PROPERTY 宣言として公開したいプロパティを含むクラスに追加します:

// Singleton.h
class Singleton : public QObject
{
    Q_OBJECT
    Q_PROPERTY(int thing READ thing WRITE setThing NOTIFY thingChanged FINAL)
    QML_ELEMENT
    QML_SINGLETON

public:
    Singleton(QObject *parent = nullptr) : QObject(parent) {}

    int thing() const { return m_value; }
    void setThing(int v)
    {
        if (v != m_value) {
            m_value = v;
            emit thingChanged();
        }
    }

signals:
    void thingChanged();

private:
    int m_value = 12;
};

これで、このモジュールをインポートした QML コードから、シングルトンのthingプロパティにアクセスできるようになります:

import QtQml

QtObject {
    objectName: "The thing is " + Singleton.thing
}

モジュールと同じディレクトリに QML ファイルを配置した場合 (これは非常に推奨されます)、モジュール内の暗黙の import からシングルトンを利用することができます。明示的にインポートする必要はありません。そうでない場合や、他のモジュールからthingプロパティにアクセスしたい場合は、そのシングルトンが属するモジュールをインポートする必要があります。

C++からプロパティの値を設定するには、シングルトンインスタンスを取得する必要があるかもしれません。そのためにはQQmlEngine::singletonInstance を使います。これを行うには、モジュール名と型名をパラメータとして与えるのが好ましい方法です:

    Singleton *singleton
            = engine->singletonInstance<Singleton *>("MyModule", "Singleton");
    singleton->setThing(77);

オブジェクト・プロパティの使用

特定のコンポーネント内のQML要素だけにプロパティを公開したい場合、 コンポーネントのルートオブジェクトに通常のプロパティとして追加することができます。また、これらのプロパティが必ず設定されるようにするために、必須プロパティ(Required Properties)とすることもできます。QMLコンポーネントを次のように記述します:

pragma ComponentBehavior: Bound

import QtQuick

Window {
    id: root
    visible: true

    required property int thing

    Text {
        anchors.fill: parent
        text: "The thing is " + root.thing
    }

    component Inner: QtObject {
        objectName: "I can see " + root.thing + " because I'm bound."
    }
}

コンポーネントのルート要素にはIDを使用し、内部のオブジェクトからはIDと名前でプロパティを参照します。ルート要素のIDをネストしたコンポーネントから安全に利用できるようにするために、ComponentBehaviorを使用します。

次に、C++では、このようなコンポーネントからオブジェクトを作成する場合、プロパティを初期化するために、QQmlComponent::createWithInitialPropertiesQQmlApplicationEngine::setInitialProperties 、またはQQuickView::setInitialProperties を必ず呼び出す必要があります。例えば、次のようになる:

    QQmlEngine engine;

    QQmlComponent component(&engine, "MyModule", "RequiredProperties");
    QScopedPointer<QObject> o(component.createWithInitialProperties({
            {"thing", 11}
    }));

これは、モジュールの URI がMyModuleであり、QML のインポートパスでモジュールが利用可能であると仮定した場合です。

本ドキュメントに含まれる文書の著作権は、それぞれの所有者に帰属します。 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。