【问题标题】:Passing Q_GADGET as signal parameter from C++ to QML将 Q_GADGET 作为信号参数从 C++ 传递到 QML
【发布时间】:2023-03-12 21:46:01
【问题描述】:

无法在 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

【问题讨论】:

    标签: c++ qt qml qtquick2 qgadget


    【解决方案1】:

    Qt 5.5 的release notes 表示新功能:

    • Qt 核心
      • 您现在可以在 Q_GADGET 中包含 Q_PROPERTY 和 Q_INVOKABLE,并且可以使用 QMetaType 系统查询此类小工具的 QMetaObject

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

    qml: Record(abc)
    qml: abc
    

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

    【讨论】:

    • Q_GADGET 不允许信号。要构建示例代码,必须使用 MEMBER 关键字:Q_PROPERTY(QString text MEMBER m_text)
    • @pixelgrease 这是一个使用小工具作为参数的信号。这不是 qgadget 的信号。答案和问题代码运行良好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多