Qt
Communication entre QML et C ++
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: