处理多个QML之间的信号

Handling signals across several QMLs

本文关键字:信号 之间 QML 处理      更新时间:2023-10-16

我刚开始学习Qt编程,在制作一个简单的测试应用程序时,发现自己在信号和插槽机制方面很吃力。

我有两个QML文件:main.QMLgarge.QML.

我有一个管理应用程序的信号和插槽的头文件:

应用程序管理员.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上启动应用程序,按下按钮时加载杂货店.qml

garge.qml上,我有一个用户可以点击的图像,并发出信号newGroceryItem()

MouseArea {
    id: okBtnClkd
    anchors.fill: parent
    Connections {
        onClicked: {
            newGroceryItem()
        }
    }
}

主应用程序main.cpp连接信号,但表示找不到信号newGroceryItem(),因为它不属于main.qml。因此,我的问题是,如何从辅助qml文件garge.qml建立到插槽addGroceryElement()的连接?

编辑:根据要求,以下是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();
}

garge.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()
                }
            }
        }
    }
}

任何QObject派生类型的方法都可以从QML代码访问,如果它是:

  • Q_INVOKABLE宏标记的公共方法
  • 作为公共Qt SLOT的方法

因此有两种方法可以访问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();
 }

现在,您可以从main.qml访问在main.cpp中创建的ApplicationManager对象,如下所示:

MouseArea {
    id: okBtnClkd
    anchors.fill: parent
    onClicked: {
        applicationManager.addGroceryItem();
    }
}

有关更多信息,请参阅此处。