Qt Communication between QML and C++ Call QML in C++


Example

To call the QML classes in C++, you need to set the objectName property.

In your Qml:

import QtQuick.Controls 2.0

Button {
    objectName: "buttonTest"
}

Then, in your C++, you can get the object with QObject.FindChild<QObject*>(QString)

Like that:

QQmlApplicationEngine engine;
QQmlComponent component(&engine, QUrl(QLatin1String("qrc:/main.qml")));

QObject *mainPage = component.create();
QObject* item = mainPage->findChild<QObject *>("buttonTest");

Now you have your QML object in your C++. But that could seems useless since we cannot really get the components of the object.

However, we can use it to send signals between the QML and the C++. To do that, you need to add a signal in your QML file like that: signal buttonClicked(string str). Once you create this, you need to emit the signal. For example:

import QtQuick 2.0
import QtQuick.Controls 2.1

    Button {
        id: buttonTest
        objectName: "buttonTest"

        signal clickedButton(string str)
        onClicked: {
            buttonTest.clickedButton("clicked !")
        }
    }

Here we have our qml button. When we click on it, it goes to the onClicked method (a base method for buttons which is called when you press the button). Then we use the id of the button and the name of the signal to emit the signal.

And in our cpp, we need to connect the signal with a slot. like that:

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlComponent>

#include "ButtonManager.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    QQmlComponent component(&engine, QUrl(QLatin1String("qrc:/main.qml")));

    QObject *mainPage = component.create();
    QObject* item = mainPage->findChild<QObject *>("buttonTest");

    ButtonManager buttonManager(mainPage);
    QObject::connect(item, SIGNAL(clickedButton(QString)), &buttonManager, SLOT(onButtonClicked(QString)));

    return app.exec();
}

As you can see, we get our qml button with findChild as before and we connect the signal to a Button manager which is a class created and who look like that. ButtonManager.h

#ifndef BUTTONMANAGER_H
#define BUTTONMANAGER_H

#include <QObject>

class ButtonManager : public QObject
{
    Q_OBJECT
public:
    ButtonManager(QObject* parent = nullptr);
public slots:
    void onButtonClicked(QString str);
};

#endif // BUTTONMANAGER_H

ButtonManager.cpp

#include "ButtonManager.h"
#include <QDebug>

ButtonManager::ButtonManager(QObject *parent)
    : QObject(parent)
{

}

void ButtonManager::onButtonClicked(QString str)
{
    qDebug() << "button: " << str;
}

So when the signal will be received, it will call the method onButtonClicked which will write "button: clicked !"

output:

enter image description here