Qt
Связь между QML и C ++
Поиск…
Вступление
Мы можем использовать QML для создания гибридных приложений, поскольку это намного проще, чем C ++. Поэтому мы должны знать, как они общаются друг с другом.
Вызов C ++ в QML
Зарегистрировать классы C ++ в QML
На стороне C ++ предположим, что у нас есть класс с именем QmlCppBridge
, он реализует метод printHello()
.
class QmlCppBridge : public QObject
{
Q_OBJECT
public:
Q_INVOKABLE static void printHello() {
qDebug() << "Hello, QML!";
}
};
Мы хотим использовать его в QML. Мы должны зарегистрировать класс, вызвав 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");
В QML используйте следующий код для его вызова:
import QmlCppBridge 1.0 // Import this module, so we can use it in our QML script
QmlCppBridge {
id: bridge
}
bridge.printHello();
Использование QQmlContext
для ввода классов или переменных C ++ в QML
Мы по-прежнему используем класс C ++ в предыдущем примере:
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);
На стороне QML:
qmlCppBridge.printHello(); // Call to C++ function
str: demoStr // Fetch value of C++ variable
Примечание. Этот пример основан на Qt 5.7. Не уверен, что он соответствует более ранним версиям Qt.
Вызов QML в C ++
Чтобы вызвать классы QML в C ++, вам нужно установить свойство objectName.
В вашем Qml:
import QtQuick.Controls 2.0
Button {
objectName: "buttonTest"
}
Затем на вашем C ++ вы можете получить объект с QObject.FindChild<QObject*>(QString)
Как это:
QQmlApplicationEngine engine;
QQmlComponent component(&engine, QUrl(QLatin1String("qrc:/main.qml")));
QObject *mainPage = component.create();
QObject* item = mainPage->findChild<QObject *>("buttonTest");
Теперь у вас есть свой объект QML в C ++. Но это может показаться бесполезным, поскольку мы не можем получить компоненты объекта.
Однако мы можем использовать его для отправки сигналов между QML и C ++. Для этого вам нужно добавить сигнал в свой QML-файл следующим образом: signal buttonClicked(string str)
. Когда вы создадите это, вам нужно испустить сигнал. Например:
import QtQuick 2.0
import QtQuick.Controls 2.1
Button {
id: buttonTest
objectName: "buttonTest"
signal clickedButton(string str)
onClicked: {
buttonTest.clickedButton("clicked !")
}
}
Здесь у нас есть кнопка qml. Когда мы нажимаем на него, он переходит к методу onClicked (базовый метод для кнопок, который вызывается при нажатии кнопки). Затем мы используем идентификатор кнопки и имя сигнала для испускания сигнала.
И в нашем cpp нам нужно соединить сигнал с слотом. как это:
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();
}
Как вы можете видеть, мы получаем нашу кнопку qml с findChild
по-прежнему, и мы подключаем сигнал к менеджеру Button, который является классом, созданным и похожим на это. 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;
}
Поэтому, когда сигнал будет принят, он вызовет метод onButtonClicked
который напишет "button: clicked !"
выход: