Embedding C++ Objects into QML with Context Properties | Qt Qml 6.8.3
Description: Description of how to embed C++ data into QML using context properties

- Qt 6.8
- Qt Qml
- Embedding C++ Objects into QML with Context Properties
- Qt 6.8.3 Reference Documentation

# Embedding C++ Objects into QML with Context Properties

Warning: By using context properties in your QML code, you create a dependency from your QML code to the specific context you have in mind when writing it. This limits re-usability of your code since the context may be different in other places where it might be used. Furthermore, the dependency is not declared. You never `import` the context or otherwise state what you expect. Therefore, anyone trying to re-use your code will have difficulties finding out whether the place of re-use has a context sufficient for your code.

Warning: Context properties are invisible to any tooling that processes QML code ahead of time, before you load it into the QML engine. The Qt Quick Compiler, qmllint, and the QML Language Server do not know anything about your context properties and will consider any access to context properties as an unqualified access.

Note: Context properties can generally be replaced either by regular properties on the root object of a component, or by singletons defined either in C++ using QML_SINGLETON or in QML using pragma Singleton.

When loading a QML object into a C++ application, it can be useful to directly embed some C++ data that can be used from within the QML code. This makes it possible, for example, to invoke a C++ method on the embedded object, or use a C++ object instance as a data model for a QML view.

The ability to inject C++ data into a QML object is made possible by the QQmlContext class. This class exposes data to the context of a QML object so that the data can be referred to directly from within the scope of the QML code.

## Setting a Simple Context Property

For example, here is a QML item that refers to a `currentDateTime` value that does not exist in the current scope:

     // MyItem.qml
     import QtQuick

     Text { text: currentDateTime }

This `currentDateTime` value can be set directly by the C++ application that loads the QML component, using QQmlContext::setContextProperty():

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

Note: Since all expressions evaluated in QML are evaluated in a particular context, if the context is modified, all bindings in that context will be re-evaluated. Thus, context properties should be used with care outside of application initialization, as this may lead to decreased application performance.

## Setting an Object as a Context Property

Context properties can hold either QVariant or QObject* values. This means custom C++ objects can also be injected using this approach, and these objects can be modified and read directly in QML. Here, we modify the above example to embed a QObject instance instead of a QDateTime value, and the QML code invokes a method on the object instance:

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() }

(Note that date/time values returned from C++ to QML can be formatted through Qt.formatDateTime() and associated functions.)

If the QML item needs to receive signals from the context property, it can connect to them using the Connections type. For example, if `ApplicationData` has a signal named `dataChanged()`, this signal can be connected to using an `onDataChanged` handler within a Connections object:

     Text {
         text: applicationData.getCurrentDateTime()

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

Context properties can be useful for using C++ based data models in a QML view. See the following examples:

- String ListModel
- Object ListModel
- AbstractItemModel

demonstrating the use of QStringList, QList<QObject*>-based models and QAbstractItemModel in QML views.

Also see the QQmlContext documentation for more information.