Recherche…


Introduction

Nous pouvons utiliser QML pour créer des applications hybrides, car il est beaucoup plus simple que C ++. Nous devrions donc savoir comment ils communiquent les uns avec les autres.

Appelez C ++ dans QML

Enregistrer les classes C ++ dans QML

Du côté du C ++, imaginez que nous avons une classe nommée QmlCppBridge , elle implémente une méthode appelée printHello() .

class QmlCppBridge : public QObject
{
    Q_OBJECT
public:
    Q_INVOKABLE static void printHello() {
        qDebug() << "Hello, QML!";
    }
};

Nous voulons l'utiliser dans le côté QML. Nous devrions enregistrer la classe en appelant qmlRegisterType() :

// Register C++ class as a QML module, 1 & 0 are the major and minor version of the QML module
qmlRegisterType<QmlCppBridge>("QmlCppBridge", 1, 0, "QmlCppBridge");

Dans QML, utilisez le code suivant pour l'appeler:

import QmlCppBridge 1.0    // Import this module, so we can use it in our QML script

QmlCppBridge {
    id: bridge
}
bridge.printHello();

Utilisation de QQmlContext pour injecter des classes ou des variables C ++ dans QML

Nous utilisons toujours la classe C ++ dans l'exemple précédent:

QQmlApplicationEngine engine;
QQmlContext *context = engine.rootContext();

// Inject C++ class to QML
context->setContextProperty(QStringLiteral("qmlCppBridge"), new QmlCppBridge(&engine));

// Inject C++ variable to QML
QString demoStr = QStringLiteral("demo");
context->setContextProperty(QStringLiteral("demoStr"), demoStr);

Côté QML:

qmlCppBridge.printHello();    // Call to C++ function
str: demoStr                  // Fetch value of C++ variable

Remarque: Cet exemple est basé sur Qt 5.7. Je ne sais pas si cela convient aux versions précédentes de Qt.

Appelez QML en C ++

Pour appeler les classes QML en C ++, vous devez définir la propriété objectName.

Dans votre Qml:

import QtQuick.Controls 2.0

Button {
    objectName: "buttonTest"
}

Ensuite, dans votre C ++, vous pouvez obtenir l'objet avec QObject.FindChild<QObject*>(QString)

Comme ça:

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

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

Maintenant, vous avez votre objet QML dans votre C ++. Mais cela peut paraître inutile puisque nous ne pouvons pas vraiment obtenir les composants de l’objet.

Cependant, nous pouvons l'utiliser pour envoyer des signaux entre le QML et le C ++. Pour ce faire, vous devez ajouter un signal dans votre fichier QML comme ceci: signal buttonClicked(string str) . Une fois que vous créez cela, vous devez émettre le signal. Par exemple:

import QtQuick 2.0
import QtQuick.Controls 2.1

    Button {
        id: buttonTest
        objectName: "buttonTest"

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

Nous avons ici notre bouton qml. Quand on clique dessus, on passe à la méthode onClicked (une méthode de base pour les boutons qui est appelée quand on appuie sur le bouton). Ensuite, nous utilisons l'id du bouton et le nom du signal pour émettre le signal.

Et dans notre cpp, nous devons connecter le signal avec un slot. comme ça:

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

Comme vous pouvez le voir, nous obtenons notre bouton qml avec findChild comme précédemment et nous connectons le signal à un gestionnaire de boutons qui est une classe créée et qui ressemble à ça. 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;
}

Donc, quand le signal sera reçu, il appellera la méthode onButtonClicked qui écrira "button: clicked !"

sortie:

entrer la description de l'image ici



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow