【问题标题】:Not able to catch the emitted signal into the QML from Qt C++无法将发出的信号从 Qt C++ 捕获到 QML
【发布时间】:2017-11-11 13:09:21
【问题描述】:

我正在用 C++ 学习 Qt。

最近我尝试从 C++ 发出信号,并基于此事件更改尝试更新 QML 中的某些内容。 emit 不工作。事实上,调试代码告诉我,emit 上方和emit 之后的代码行已经工作了。但是emit 本身不起作用。

根据我目前的理解,您 emit 是来自 C++ 的信号,on+signal nameQML 内部使用以访问该事件。

我在这里做错了什么?

这是问题的简化版本:

emitsignal.h

#ifndef EMITSIGNAL_H
#define EMITSIGNAL_H

#include <QObject>

class EmitSignal : public QObject
{
    Q_OBJECT
public:
    explicit EmitSignal(QObject *parent = nullptr);
    int add(int, int);

signals:
    void mySignal();

public slots:
};

#endif // EMITSIGNAL_H

emitsignal.cpp

#include "emitsignal.h"

#include <QDebug>

EmitSignal::EmitSignal(QObject *parent) : QObject(parent) {}

int EmitSignal::add(int x, int y)
{
    int z = x + y;

    qDebug() << z;

    emit mySignal();

    return x + y;
}

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>

#include "emitsignal.h"

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    qmlRegisterType<EmitSignal>("com", 1, 0, "EmitSignal");

    EmitSignal em;
    em.add(1,2);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

main.qml

import QtQuick 2.8
import QtQuick.Window 2.2

import com 1.0

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    EmitSignal {
    id: emitSignal
    onMySignal: console.log('Inside the function')
    }

}

【问题讨论】:

    标签: c++ qt qml qt5 qt-signals


    【解决方案1】:

    当使用qmlRegisterType 时,该类型正在注册,因此带有id:emitSignalEmitSignal 对象与em 对象不同(除非该类实现了单例,但在您的情况下它不是) , 即使为对象 em 发出信号,也不会为 id:emitSignal 的项目发出信号。

    如果您希望它们是同一个对象,您必须使用setContextProperty 并与Connections 建立连接,并且您不应该在QML 窗口加载之前调用发出信号的方法。

    ma​​in.cpp

    #include "emitsignal.h"
    
    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QQmlContext>
    
    int main(int argc, char *argv[])
    {
        QGuiApplication app(argc, argv);
    
        EmitSignal em;
        QQmlApplicationEngine engine;
        engine.rootContext()->setContextProperty("EmitSignal", &em); // EmitSignal is the id
    
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
        if (engine.rootObjects().isEmpty())
            return -1;
        em.add(1,2);
        return app.exec();
    }
    

    ma​​in.qml

    import QtQuick 2.8
    import QtQuick.Window 2.2
    
    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
    
        Connections {
            target: EmitSignal
            onMySignal: console.log('Inside the function')
        }
    }
    

    参考资料:

    【讨论】:

    • 我在类内部而不是在主(在我的应用程序中)中创建对象,因此无法创建引擎并从主外部加载它。还是有解决办法?
    • 不,我的班级没有实现单例。
    • 它适用于实际问题,因此我接受了它作为答案。没问题。但我想在class 中设置此上下文属性,而不是在main() 中,这就是问题所在。
    • 跨方法/类传递指向对象的指针是不好的。这就是我读到的。
    • 我会做一个简化版的问题,几分钟后分享给大家。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-20
    • 1970-01-01
    • 2012-02-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多