Qt
Komunikacja między QML i C ++
Szukaj…
Wprowadzenie
Możemy używać QML do tworzenia aplikacji hybrydowych, ponieważ jest to o wiele łatwiejsze niż C ++. Powinniśmy więc wiedzieć, jak się ze sobą komunikują.
Wywołaj C ++ w QML
Zarejestruj klasy C ++ w QML
Wyobraźmy sobie, że po stronie C ++ mamy klasę o nazwie QmlCppBridge
, która implementuje metodę o nazwie printHello()
.
class QmlCppBridge : public QObject
{
Q_OBJECT
public:
Q_INVOKABLE static void printHello() {
qDebug() << "Hello, QML!";
}
};
Chcemy go używać po stronie QML. Powinniśmy zarejestrować klasę, wywołując 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");
W QML użyj następującego kodu, aby go wywołać:
import QmlCppBridge 1.0 // Import this module, so we can use it in our QML script
QmlCppBridge {
id: bridge
}
bridge.printHello();
Użycie QQmlContext
do wstrzyknięcia klas lub zmiennych C ++ do QML
Nadal używamy klasy C ++ w poprzednim przykładzie:
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);
Po stronie QML:
qmlCppBridge.printHello(); // Call to C++ function
str: demoStr // Fetch value of C++ variable
Uwaga: ten przykład oparty jest na Qt 5.7. Nie jestem pewien, czy pasuje do wcześniejszych wersji Qt.
Wywołaj QML w C ++
Aby wywołać klasy QML w C ++, musisz ustawić właściwość objectName.
W swoim Qml:
import QtQuick.Controls 2.0
Button {
objectName: "buttonTest"
}
Następnie w swoim C ++ możesz uzyskać obiekt za pomocą QObject.FindChild<QObject*>(QString)
Tak:
QQmlApplicationEngine engine;
QQmlComponent component(&engine, QUrl(QLatin1String("qrc:/main.qml")));
QObject *mainPage = component.create();
QObject* item = mainPage->findChild<QObject *>("buttonTest");
Teraz masz swój obiekt QML w swoim C ++. Ale to może wydawać się bezużyteczne, ponieważ tak naprawdę nie możemy uzyskać składników obiektu.
Możemy go jednak użyć do wysyłania sygnałów między QML a C ++. Aby to zrobić, musisz dodać sygnał do pliku QML w następujący sposób: przycisk signal buttonClicked(string str)
. Po utworzeniu musisz wyemitować sygnał. Na przykład:
import QtQuick 2.0
import QtQuick.Controls 2.1
Button {
id: buttonTest
objectName: "buttonTest"
signal clickedButton(string str)
onClicked: {
buttonTest.clickedButton("clicked !")
}
}
Tutaj mamy nasz przycisk qml. Kiedy klikamy na nią, przechodzi do metody onClicked (podstawowa metoda dla przycisków, która jest wywoływana po naciśnięciu przycisku). Następnie używamy identyfikatora przycisku i nazwy sygnału, aby wyemitować sygnał.
A w naszym procesorze musimy połączyć sygnał ze szczeliną. tak:
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();
}
Jak widać, otrzymujemy nasz przycisk qml z findChild
jak poprzednio i łączymy sygnał z menedżerem Button, który jest klasą utworzoną i który wygląda tak. 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;
}
Kiedy więc sygnał zostanie odebrany, wywoła metodę onButtonClicked
która zapisze "button: clicked !"
wynik: