Integrating QML and C++ | Qt QML 6.1.0

- Qt 6.1
- Qt QML
- Integrating QML and C++
- Qt 6.1.0 Reference Documentation

# Integrating QML and C++

QML applications often need to handle more advanced and performance-intensive tasks in C++. The most common and quickest way to do this is to expose the C++ class to the QML runtime, provided the C++ implementation is derived from QObject. Assuming that you have Qt 5.7 or later installed, the following step-by-step instructions guide you through the process of using the C++ class, BackEnd, in a QML application:

1. Create a new project using the "Qt Quick Application" template in Qt Creator

   Note: Uncheck the With ui.qml file option in the Define Project Details section of New Project Wizard.

2. Add a new C++ class called `BackEnd` to the project and replace its header file contents with:

        #ifndef BACKEND_H
        #define BACKEND_H

        #include <QObject>
        #include <QString>
        #include <qqml.h>

        class BackEnd : public QObject
        {
            Q_OBJECT
            Q_PROPERTY(QString userName READ userName WRITE setUserName NOTIFY userNameChanged)
            QML_ELEMENT

        public:
            explicit BackEnd(QObject *parent = nullptr);

            QString userName();
            void setUserName(const QString &userName);

        signals:
            void userNameChanged();

        private:
            QString m_userName;
        };

        #endif // BACKEND_H

   The `Q_PROPERTY` macro declares a property that could be accessed from QML. The `QML_ELEMENT` macro makes the BackEnd class available in QML.

3. Add the following lines to your project file:

        CONFIG += qmltypes
        QML_IMPORT_NAME = io.qt.examples.backend
        QML_IMPORT_MAJOR_VERSION = 1

   The BackEnd class is automatically registered as a type, which is accessible from QML by importing the URL, "`io.qt.examples.backend 1.0`".

4. Replace the contents of `backend.cpp` with:

        #include "backend.h"

        BackEnd::BackEnd(QObject *parent) :
            QObject(parent)
        {
        }

        QString BackEnd::userName()
        {
            return m_userName;
        }

        void BackEnd::setUserName(const QString &userName)
        {
            if (userName == m_userName)
                return;

            m_userName = userName;
            emit userNameChanged();
        }

   The `setUserName` function emits the `userNameChanged` signal every time `m_userName` value changes. The signal can be handled from QML using the `onUserNameChanged` handler.

5. Replace the contents of `main.qml` with the following code:

        import QtQuick 2.6
        import QtQuick.Controls 2.0
        import io.qt.examples.backend 1.0

        ApplicationWindow {
            id: root
            width: 300
            height: 480
            visible: true

            BackEnd {
                id: backend
            }

            TextField {
                text: backend.userName
                placeholderText: qsTr("User name")
                anchors.centerIn: parent

                onEditingFinished: backend.userName = text
            }
        }

   The `BackEnd` instance lets you access the `userName` property, which is updated when the TextField's `text` property changes.

Now the application can be run.

Application running on Ubuntu

Qt offers several methods to integrate C++ with QML, and the method discussed in this tutorial is just one of them. For more details about these methods, refer to Overview - QML and C++ Integration.