Qt
Communicatie tussen QML en C ++
Zoeken…
Invoering
We kunnen QML gebruiken om hybride applicaties te bouwen, omdat het veel eenvoudiger is dan C ++. We moeten dus weten hoe ze met elkaar communiceren.
Roep C ++ aan in QML
Registreer C ++ klassen in QML
Stel je aan C ++ kant voor dat we een klasse hebben met de naam QmlCppBridge
, deze implementeert een methode genaamd printHello()
.
class QmlCppBridge : public QObject
{
Q_OBJECT
public:
Q_INVOKABLE static void printHello() {
qDebug() << "Hello, QML!";
}
};
We willen het gebruiken in QML-zijde. We moeten de klasse registreren door qmlRegisterType()
aan te roepen:
// 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");
Gebruik in QML de volgende code om het aan te roepen:
import QmlCppBridge 1.0 // Import this module, so we can use it in our QML script
QmlCppBridge {
id: bridge
}
bridge.printHello();
QQmlContext
gebruiken om C ++ klassen of variabelen in QML te injecteren
We gebruiken de C ++ -klasse nog steeds in het vorige voorbeeld:
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);
Aan QML-zijde:
qmlCppBridge.printHello(); // Call to C++ function
str: demoStr // Fetch value of C++ variable
Opmerking: dit voorbeeld is gebaseerd op vraag 5.7. Niet zeker of het in eerdere Qt-versies past.
Roep QML op in C ++
Om de QML-klassen in C ++ aan te roepen, moet u de eigenschap objectName instellen.
In uw Qml:
import QtQuick.Controls 2.0
Button {
objectName: "buttonTest"
}
Vervolgens kunt u in uw C ++ het object QObject.FindChild<QObject*>(QString)
met QObject.FindChild<QObject*>(QString)
Zoals dat:
QQmlApplicationEngine engine;
QQmlComponent component(&engine, QUrl(QLatin1String("qrc:/main.qml")));
QObject *mainPage = component.create();
QObject* item = mainPage->findChild<QObject *>("buttonTest");
Nu heb je je QML-object in je C ++. Maar dat zou nutteloos kunnen lijken, omdat we de componenten van het object niet echt kunnen krijgen.
We kunnen het echter gebruiken om signalen tussen de QML en de C ++ te verzenden. Om dat te doen, moet je een signaal als volgt in je QML-bestand toevoegen: signal buttonClicked(string str)
. Nadat u dit hebt gemaakt, moet u het signaal uitzenden. Bijvoorbeeld:
import QtQuick 2.0
import QtQuick.Controls 2.1
Button {
id: buttonTest
objectName: "buttonTest"
signal clickedButton(string str)
onClicked: {
buttonTest.clickedButton("clicked !")
}
}
Hier hebben we onze qml-knop. Wanneer we erop klikken, gaat het naar de onClicked- methode (een basismethode voor knoppen die wordt opgeroepen wanneer u op de knop drukt). Vervolgens gebruiken we de id van de knop en de naam van het signaal om het signaal uit te zenden.
En in onze cpp moeten we het signaal verbinden met een slot. zoals dat:
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();
}
Zoals u kunt zien, krijgen we onze qml-knop met findChild
als voorheen en we verbinden het signaal met een Button-manager die een klasse is gemaakt en die er zo uitziet. 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;
}
Dus wanneer het signaal wordt ontvangen, wordt de methode onButtonClicked
die "button: clicked !"
output: