c++ - 将 Q_GADGET 作为信号参数从 C++ 传递到 QML

标签 c++ qt qml qtquick2 qgadget

无法在 QML 代码中获取 C++ 对象的属性。 对象作为参数传递给信号。

期望在QML中,可以提取Record对象的text属性。该值应为 abc。 QML 将对象视为 QVariant(Record),将其属性 text 视为 undefined

Record 是一个类似于QPoint 的值类型,所以它使用Q_GADGET 声明。

hpp:

#ifndef LISTENP_HPP_
#define LISTENP_HPP_

#include <QObject>

#include "Record.hpp"

class ListenP: public QObject
{
Q_OBJECT

public:
    ListenP();
    virtual ~ListenP();

    void emitGotRecord();

signals:
    void gotRecord(Record r);
};

#endif /* LISTENP_HPP_ */

cpp:

#include "ListenP.hpp"

ListenP::ListenP() :
        QObject()
{
}

ListenP::~ListenP()
{
}

void ListenP::emitGotRecord()
{
    emit gotRecord(Record("abc"));
}

hpp 记录:

#ifndef RECORD_HPP_
#define RECORD_HPP_

#include <QObject>
#include <QMetaType>

class Record
{
Q_GADGET

Q_PROPERTY(QString text READ text WRITE setText)

public:
    Record(const QString& text = "");
    ~Record();

    QString text() const
    {
        return m_text;
    }

    void setText(const QString& text)
    {
        m_text = text;
    }

private:
    QString m_text;
};

Q_DECLARE_METATYPE(Record)

#endif /* RECORD_HPP_ */

用于记录的 cpp:

#include "Record.hpp"

Record::Record(const QString& text) :
        m_text(text)
{
}

Record::~Record()
{
}

namespace
{
const int RecordMetaTypeId = qMetaTypeId<Record>();
}

QML 部分:

Connections {
    target: listenPModel
    onGotRecord: {
        console.log(r)
        console.log(r.text)
    }
}

主要部分:

QGuiApplication app(argc, argv);

auto listenP = std::make_shared<ListenP>();
QQuickView view;
view.rootContext()->setContextProperty("listenPModel", &*listenP);
view.setSource(QStringLiteral("src/qml/main.qml"));
view.show();

QtConcurrent::run([=]
{
    QThread::sleep(3);
    listenP->emitGotRecord();
});

return app.exec();

日志显示:

qml: QVariant(Record)
qml: undefined

最佳答案

release notes对于 Qt 5.5 的新特性:

  • Qt Core
    • You can now have Q_PROPERTY and Q_INVOKABLE within a Q_GADGET, and there is a way to query the QMetaObject of such gadget using the QMetaType system

确实,使用 Qt 5.4 编译和运行您的示例得到的结果与使用 Qt 5.5 的示例相同我得到了正确识别的 Record,即我得到的结果是:

qml: Record(abc)
qml: abc

此外,如 Q_DECLARE_METATYPE 中所述 documentation ,传递给宏的类型 - Record 在这种情况下,应该提供 (1) 公共(public)默认构造函数,(2) 公共(public)复制构造函数和 (3) 公共(public)析构函数。由于 Record 是一个非常简单的类,因此无需提供复制构造函数,因为默认的就足够了。

关于c++ - 将 Q_GADGET 作为信号参数从 C++ 传递到 QML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31433260/

相关文章:

c++ - 在 C++ 中调用带括号的枚举/枚举类时发生了什么?

c++ - lambdas 和 std::function 的包装器

qt - 如何阻止鼠标中键单击取消选择 QGraphicsScene 中的项目而不阻止它从场景中的项目?

qt - Qt Quick 1.1/QML 的文本缩放效果不佳

c++ - QML Qt- 解析 XML 并将其转换为 LisView 的 ListModel

c++ - 为什么 VS2015 中模板相关的嵌套类型名称不需要 typename 关键字?

c++ - QT:未生成 ui_* 文件

c++ - 使用 qt c++ 在 BlackBerry 10 应用程序的屏幕中间显示按钮

c++ - QML 信号连接

C++ 静态代码分析 - 显示语句或行中使用的 header