Обработка сигналов через несколько QML
Я только начал изучать программирование на Qt и обнаружил, что борюсь с механизмом сигналов и слотов, создавая простое тестовое приложение.
У меня есть два файла QML: main.qml и grocery.qml.
У меня есть заголовочный файл, который управляет сигналами и слотами приложения:
applicationamanger.h
#ifndef APPLICATIONMANAGER_H
#define APPLICATIONMANAGER_H
#include <QObject>
#include <QDebug>
class ApplicationManager : public QObject
{
Q_OBJECT
public:
explicit ApplicationManager(QObject *parent = 0);
signals:
void newGroceryItem();
public slots:
void addGroceryItem();
};
#endif // APPLICATIONMANAGER_H
Пользователь запускает приложение на main.qml и при нажатии кнопки загружает grocery.qml
На grocery.qml у меня есть изображение, которое может быть нажата пользователем и испускает сигнал newGroceryItem()
MouseArea {
id: okBtnClkd
anchors.fill: parent
Connections {
onClicked: {
newGroceryItem()
}
}
}
И основное приложение main.cpp соединяет сигналы, но говорит, что не может найти сигнал newGroceryItem(), поскольку он не принадлежит main.qml. Итак, мой вопрос, как я могу установить соединение со слотом addGroceryItem() из вторичного файла qml grocery.qml?
РЕДАКТИРОВАТЬ: В соответствии с просьбой, вот содержимое main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickWindow>
#include <QQmlContext>
#include "applicationmanager.h"
int main(int argc, char *argv[]){
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
QObject *topLevel = engine.rootObjects().value(0);
QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);
ApplicationManager applicationManager;
QObject::connect(window, SIGNAL(newGroceryItem()), &applicationManager, SLOT(addGroceryItem()));
return app.exec();
}
И содержимое grocery.qml
import QtQuick 2.5
import QtQuick.Controls 1.4
ApplicationWindow {
//Declaration of signals.
signal newGroceryItem()
width: 300
height: 400
visible: true
TextField {
id: product
x: 14
y: 111
width: 270
height: 22
}
Text {
id: text1
x: 14
y: 81
width: 124
height: 24
text: qsTr("Product")
font.pixelSize: 20
}
Image {
id: okBtn
x: 99
y: 290
width: 100
height: 100
source: "img/main/okBtn.png"
MouseArea {
id: okBtnClkd
anchors.fill: parent
Connections {
onClicked: {
newGroceryItem()
}
}
}
}
}
1 ответ
Любой метод QObject
-приобретенный тип доступен из кода QML, если он:
- публичный метод помечен с
Q_INVOKABLE
макрос - метод, который является публичным слотом Qt
Таким образом, есть два способа доступа addGroceryItem()
, Первый заключается в использовании Q_INVOKABLE
макрос следующим образом:
class ApplicationManager : public QObject
{
Q_OBJECT
public:
explicit ApplicationManager(QObject *parent = 0);
Q_INVOKABLE void addGroceryItem();
};
Второй способ заключается в использовании public slots
следующее:
class ApplicationManager : public QObject
{
Q_OBJECT
public:
explicit ApplicationManager(QObject *parent = 0);
public slots:
void addGroceryItem();
};
Если вы создаете свой объект класса в C++, тогда вы должны установить объект в качестве данных контекста для main.qml
следующее:
int main(int argc, char *argv[]) {
QCoreApplication app(argc, argv);
QQmlEngine engine;
ApplicationManager app;
engine.rootContext()->setContextProperty("applicationManager", &app);
QQmlComponent component(&engine, QUrl::fromLocalFile("main.qml"));
component.create();
return app.exec();
}
Теперь вы можете получить доступ к ApplicationManager
объект, созданный в main.cpp
от main.qml
следующее:
MouseArea {
id: okBtnClkd
anchors.fill: parent
onClicked: {
applicationManager.addGroceryItem();
}
}
Для получения дополнительной информации см. Здесь.