如何从QML收听C ++信号?

时间:2015-05-01 21:14:24

标签: c++ qt qml qt-creator

我有我称之为C ++"服务"谁想要向QML公开接口。我尝试使用QQmlContext's setContextProperty将对象链接到QML并从QML Connections block连接到它。

QML并没有像之前在QML上下文中注册服务那样抱怨引用错误:

qrc:/main.qml:13: ReferenceError: service is not defined

因此,QML似乎现在找到service对象,但是没有调用QML槽javascript函数。我在Qt Creator中看到了这一点:

Debugging starts
QML debugging is enabled. Only use this in a safe environment.
QML Debugger: Waiting for connection on port 62301...
Calling the clbk signal
Debugging has finished

每个In onClbk应该有console.log("In onClbk");条消息我知道我可以使用QMetaObject::invokeMethod直接调用QML对象的功能,但我想尝试一下通过使用信号和插槽来实现更松散的耦合。

如果可能的话,我想避免创建QQuickItem并在QML中实例化服务。

不幸的是,样板代码很多,这是我的SSCCE

Here is a zip file of all the project directory as created through Qt Creator 5.4.

的main.cpp

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;
    auto rc = engine.rootContext();
    auto service = new Service();
    engine.rootContext()->setContextProperty(QStringLiteral("service"), service);
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    // invoke the trigger arbitrarily
    QTimer *timer = new QTimer();
    timer->setSingleShot(true);
    QObject::connect(timer, SIGNAL(timeout()), service, SLOT(trigger_clbk()));
    timer->start(4000);
    return app.exec();
}

service.h

class Service : public QQuickItem {
    Q_OBJECT

public:
    virtual ~Service(){}
signals:
    void clbk();
public slots:
    void trigger_clbk() {
        qDebug()<<"Calling the clbk signal";
        clbk();
    }
};

main.qml

import QtQuick 2.4
import QtQuick.Window 2.2

Window {
    visible: true
    MainForm {
        anchors.fill: parent
        mouseArea.onClicked: {
            Qt.quit();
        }
        // subscribe to a signal
        Connections {
            target: service
            onClbk: function(){
                console.log("In onClbk");
            }
        }
    }
}

Main.ui.qml

import QtQuick 2.3

Rectangle {
    property alias mouseArea: mouseArea

    width: 360
    height: 360

    MouseArea {
        id: mouseArea
        anchors.fill: parent
    }

    Text {
        anchors.centerIn: parent
        text: "Hello World"
    }
}

1 个答案:

答案 0 :(得分:-1)

  1. 您应该明确使用服务类型,例如Service或QObject(非自动)。确保你想要对象做什么对你有好处。

  2. 无需在QML的SLOT中定义附加功能,因为它本身就是一个功能。如果您想使用参数,请执行以下操作:

    signals:
    void clbk(QString signalString);
    
    Connections {
    target: service
    onClbk: {
        console.log(signalString);
    }
    }
    
  3. 请注意,您必须使用参数的确切名称,并且必须使用qRegisterMetaType注册params的类型。