Qt
Comunicación entre QML y C ++.
Buscar..
Introducción
Podemos usar QML para construir aplicaciones híbridas, ya que es mucho más fácil que C ++. Así que deberíamos saber cómo se comunican entre sí.
Llama a C ++ en QML
Registrar clases de C ++ en QML
En el lado de C ++, imagine que tenemos una clase llamada QmlCppBridge
, que implementa un método llamado printHello()
.
class QmlCppBridge : public QObject
{
Q_OBJECT
public:
Q_INVOKABLE static void printHello() {
qDebug() << "Hello, QML!";
}
};
Queremos usarlo en el lado QML. Debemos registrar la clase llamando a 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");
En QML, usa el siguiente código para llamarlo:
import QmlCppBridge 1.0 // Import this module, so we can use it in our QML script
QmlCppBridge {
id: bridge
}
bridge.printHello();
Uso de QQmlContext
para inyectar clases o variables de C ++ a QML
Todavía usamos la clase C ++ en el ejemplo anterior:
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);
En el lado QML:
qmlCppBridge.printHello(); // Call to C++ function
str: demoStr // Fetch value of C++ variable
Nota: Este ejemplo se basa en Qt 5.7. No estoy seguro si se ajusta a versiones anteriores de Qt.
Llame a QML en C ++
Para llamar a las clases QML en C ++, debe establecer la propiedad objectName.
En tu Qml:
import QtQuick.Controls 2.0
Button {
objectName: "buttonTest"
}
Luego, en su C ++, puede obtener el objeto con QObject.FindChild<QObject*>(QString)
Como eso:
QQmlApplicationEngine engine;
QQmlComponent component(&engine, QUrl(QLatin1String("qrc:/main.qml")));
QObject *mainPage = component.create();
QObject* item = mainPage->findChild<QObject *>("buttonTest");
Ahora tienes tu objeto QML en tu C ++. Pero eso podría parecer inútil ya que realmente no podemos obtener los componentes del objeto.
Sin embargo, podemos usarlo para enviar señales entre el QML y el C ++. Para hacer eso, necesita agregar una señal en su archivo QML como esa: signal buttonClicked(string str)
. Una vez que creas esto, necesitas emitir la señal. Por ejemplo:
import QtQuick 2.0
import QtQuick.Controls 2.1
Button {
id: buttonTest
objectName: "buttonTest"
signal clickedButton(string str)
onClicked: {
buttonTest.clickedButton("clicked !")
}
}
Aquí tenemos nuestro botón qml. Cuando hacemos clic en él, va al método onClicked (un método base para los botones que se llama cuando se presiona el botón). Luego usamos la identificación del botón y el nombre de la señal para emitir la señal.
Y en nuestro cpp, necesitamos conectar la señal con una ranura. como eso:
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();
}
Como puede ver, obtenemos nuestro botón qml con findChild
como antes y conectamos la señal a un administrador de botones que es una clase creada y que se parece a eso. 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;
}
Entonces, cuando se reciba la señal, llamará al método onButtonClicked
que escribirá "button: clicked !"
salida: