Qt
Comunicazione tra QML e C ++
Ricerca…
introduzione
Possiamo usare QML per costruire applicazioni ibride, dal momento che è molto più facile di C ++. Quindi dovremmo sapere come comunicano tra loro.
Chiama C ++ in QML
Registra le classi C ++ in QML
In C ++, immaginiamo di avere una classe chiamata QmlCppBridge
, che implementa un metodo chiamato printHello()
.
class QmlCppBridge : public QObject
{
Q_OBJECT
public:
Q_INVOKABLE static void printHello() {
qDebug() << "Hello, QML!";
}
};
Vogliamo usarlo in QML. Dovremmo registrare la classe chiamando 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");
In QML, usa il seguente codice per chiamarlo:
import QmlCppBridge 1.0 // Import this module, so we can use it in our QML script
QmlCppBridge {
id: bridge
}
bridge.printHello();
Usando QQmlContext
per iniettare classi o variabili C ++ in QML
Usiamo ancora la classe C ++ nell'esempio precedente:
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);
Sul lato QML:
qmlCppBridge.printHello(); // Call to C++ function
str: demoStr // Fetch value of C++ variable
Nota: questo esempio si basa su Qt 5.7. Non sono sicuro se si adatta alle versioni precedenti di Qt.
Chiama QML in C ++
Per chiamare le classi QML in C ++, è necessario impostare la proprietà objectName.
Nel tuo Qml:
import QtQuick.Controls 2.0
Button {
objectName: "buttonTest"
}
Quindi, nel tuo C ++, puoi ottenere l'oggetto con QObject.FindChild<QObject*>(QString)
Come quello:
QQmlApplicationEngine engine;
QQmlComponent component(&engine, QUrl(QLatin1String("qrc:/main.qml")));
QObject *mainPage = component.create();
QObject* item = mainPage->findChild<QObject *>("buttonTest");
Ora hai il tuo oggetto QML nel tuo C ++. Ma ciò potrebbe sembrare inutile dal momento che non possiamo davvero ottenere i componenti dell'oggetto.
Tuttavia, possiamo usarlo per inviare segnali tra QML e C ++. Per fare ciò, è necessario aggiungere un segnale nel file QML in questo modo: signal buttonClicked(string str)
. Una volta creato questo, è necessario emettere il segnale. Per esempio:
import QtQuick 2.0
import QtQuick.Controls 2.1
Button {
id: buttonTest
objectName: "buttonTest"
signal clickedButton(string str)
onClicked: {
buttonTest.clickedButton("clicked !")
}
}
Qui abbiamo il nostro pulsante qml. Quando facciamo clic su di esso, si passa al metodo onClicked (un metodo di base per i pulsanti che viene chiamato quando si preme il pulsante). Quindi usiamo l'id del pulsante e il nome del segnale per emettere il segnale.
E nel nostro cpp, dobbiamo connettere il segnale con uno slot. come quello:
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();
}
Come puoi vedere, otteniamo il nostro pulsante qml con findChild
come prima e colleghiamo il segnale a un gestore Button che è una classe creata e che assomiglia a quella. 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;
}
Quindi, quando il segnale sarà ricevuto, chiamerà il metodo onButtonClicked
che scriverà "button: clicked !"
onButtonClicked
"button: clicked !"
produzione: