コンテキストプロパティを使ったC++オブジェクトのQMLへの埋め込み

警告 QMLのコードにコンテキスト・プロパティを使用すると、 QMLのコードと、そのコードを書いたときに想定した特定のコンテキストとの間に 依存関係ができてしまいます。このことはコードの再利用性を制限することになります。さらに、依存関係は宣言されません。あなたは、import 、あるいは、あなたが何を期待しているかを述べることはありません。したがって、あなたのコードを再利用しようとする人は、再利用先があなたのコードに十分なコンテキストを持っているかどうかを見つけるのが難しくなります。

警告 コンテキスト・プロパティは、QMLコードをQMLエンジンに読み込む前に処理するツールからは見えません。Qt Quick Compilerqmllint、およびQML Language Serverはコンテキストプロパティについて何も知らないため、コンテキストプロパティへのアクセスはすべて非修飾アクセスとみなされます。

注意: コンテキスト・プロパティは一般に、コンポーネントのルート・オブジェクトの通常のプロパティか、C++でQML_SINGLETON 、QMLでプラグマ・シングルトンを使って定義されたシングルトンで置き換えることができます。

QMLオブジェクトをC++アプリケーションに読み込む際、QMLコード内から利用可能なC++データを直接埋め込むと便利です。これにより、例えば、埋め込まれたオブジェクトに対してC++のメソッドを呼び出したり、C++オブジェクトのインスタンスをQMLビューのデータモデルとして使用したりすることが可能になります。

C++のデータをQMLオブジェクトに注入する機能は、QQmlContext クラスによって実現されています。このクラスはQMLオブジェクトのコンテキストにデータを公開し、 QMLコードの範囲内からデータを直接参照できるようにします。

単純なコンテキスト・プロパティの設定

例えば、currentDateTime の値を参照する QML の項目がありますが、これは現在のスコープには存在しません:

// MyItem.qml
import QtQuick

Text { text: currentDateTime }

このcurrentDateTime の値は、QMLコンポーネントをロードするC++アプリケーションから、QQmlContext::setContextProperty()を使って直接設定することができます:

QQuickView view;
view.rootContext()->setContextProperty("currentDateTime", QDateTime::currentDateTime());
view.setSource(QUrl::fromLocalFile("MyItem.qml"));
view.show();

注意: QMLで評価される式はすべて特定のコンテキストの中で評価されるため、 コンテキストが変更されると、そのコンテキストの中のすべてのバインディングが 再評価されます。そのため、アプリケーションの初期化以外では、コンテキストプロパティの使用には注意が必要です。

コンテキスト・プロパティとしてオブジェクトを設定する

コンテキスト・プロパティは、QVariant またはQObject* の値を保持することができます。つまり、C++のカスタムオブジェクトをこの方法で注入することも可能であり、これらのオブジェクトをQMLで直接変更したり読み込んだりすることができます。ここでは、QDateTime の値の代わりに、QObject のインスタンスを埋め込み、QMLコードはそのオブジェクトインスタンスのメソッドを呼び出します:

C++
class ApplicationData : public QObject
{
    Q_OBJECT
public:
    Q_INVOKABLE QDateTime getCurrentDateTime() const {
        return QDateTime::currentDateTime();
    }
};

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

    QQuickView view;

    ApplicationData data;
    view.rootContext()->setContextProperty("applicationData", &data);

    view.setSource(QUrl::fromLocalFile("MyItem.qml"));
    view.show();

    return app.exec();
}
QML
// MyItem.qml
import QtQuick

Text { text: applicationData.getCurrentDateTime() }

(C++からQMLに返される日付/時刻の値は、Qt.formatDateTime()や関連する関数によって整形できることに注意してください)

QMLの項目がコンテキスト・プロパティからシグナルを受け取る必要がある場合、Connections の型を使ってシグナルに接続することができます。例えば、ApplicationDatadataChanged() というシグナルがある場合、このシグナルはConnections オブジェクトの中のonDataChanged ハンドラを使って接続することができます:

Text {
    text: applicationData.getCurrentDateTime()

    Connections {
        target: applicationData
        onDataChanged: console.log("The application data changed!")
    }
}

コンテキスト・プロパティは、C++ベースのデータモデルをQMLビューで使用する際 に便利です。以下の例を参照してください:

QStringListQList<QObject*>ベースのモデル、QAbstractItemModel を QML ビューで使用する例を示します。

また、QQmlContext のドキュメントも参照してください。

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