将Q_GADGET作为信号参数从C ++传递到QML [英] Passing Q_GADGET as signal parameter from C++ to QML

查看:531
本文介绍了将Q_GADGET作为信号参数从C ++传递到QML的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Can't get a property of a C++ object inside a QML code. Object is passed as a parameter to the signal.

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

Expected that in QML, the property text of the Record object can be extracted. And the value should be abc. QML sees the object as QVariant(Record), and its property text as undefined.

Record是类似于QPoint的值类型,因此它使用Q_GADGET声明.

Record is a value-type like QPoint, so it uses Q_GADGET declaration.

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

推荐答案

发行说明 Qt 5.5表示新功能:

The release notes for Qt 5.5 says for the new features:

  • Qt核心
    • 您可以现在在Q_GADGET中包含Q_PROPERTY和Q_INVOKABLE ,并且有一种方法可以使用QMetaType系统查询此类小工具的QMetaObject
  • 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,即我得到了一个结果:

Indeed, compiling and running your example with Qt 5.4 gives the same result as yours whereas with Qt 5.5 I got Record correctly recognised, i.e. I got as a result:

qml: Record(abc)
qml: abc

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

Also, as stated in the Q_DECLARE_METATYPE documentation, the type passed to the macro - Record in this case, should provide (1) a public default constructor, (2) a public copy constructor and (3) a public destructor. Since Record is a very simple class, there's no need to provide a copy constructor as the default one is sufficient.

这篇关于将Q_GADGET作为信号参数从C ++传递到QML的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆