Passing Q_GADGET as signal parameter from C++ to QML

喜夏-厌秋 提交于 2019-11-28 08:51:22

问题


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

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 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 for Record:

#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 for Record:

#include "Record.hpp"

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

Record::~Record()
{
}

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

QML piece:

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

main piece:

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();

Log shows:

qml: QVariant(Record)
qml: undefined

回答1:


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

  • 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

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

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.



来源:https://stackoverflow.com/questions/31433260/passing-q-gadget-as-signal-parameter-from-c-to-qml

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!