简体   繁体   中英

How to pass QVector<Custom_Q_GADGET> to QML?

I have QObject class with 2 properties:

class Foo : public QObject {
Q_OBJECT
    Q_PROPERTY(QVector<Namespace1::Namespace2::Item> items READ getItemVector)
    Q_PROPERTY(QVector<QString> tests READ getTestVector)
    ...
}

QVector<Namespace1::Namespace2::Item> Foo::getItemVector() const
{
    return _item_vector;
}

QVector<QString> Foo::getTestVector() const
{
    return _test_vector;
}

Everything is ok with QVector of QString s in the QML, but I was not able to pass QVector of Namespace1::Namespace2::Item s.

Output to QML console gives me: QVariant(QVector<Namespace1::Namespace2:Item>) for console.log(foo.items) and length = undefined for console.log(foo.items.length)

What I have found out from the Qt documentation:

These sequence types are implemented directly in terms of the underlying C++ sequence. There are two ways in which such sequences can be exposed to QML: as a Q_PROPERTY of the given sequence type; or as the return type of a Q_INVOKABLE method.

...

In particular, QML currently supports: ... QList< QString >... and all registered QList, QVector, QQueue, QStack, QSet, QLinkedList, std::list, std::vector that contain a type marked with Q_DECLARE_METATYPE.

As I understand, everything boils down simply to:

Q_DECLARE_METATYPE(Namespace1::Namespace2::Item)

Besides this:

Some types are registered automatically and do not need this macro: Pointers to classes derived from QObject, QList< T >, QVector< T > , QQueue< T >, QStack< T >, QSet< T > or QLinkedList where T is a registered meta type

However, I also tried to declare metatype(without luck, obviously):

Q_DECLARE_METATYPE(QVector<Namespace1::Namespace2::Item>)

and also tried to register metatypes(without any luck as well):

qRegisterMetaType<Namespace1::Namespace2::Item>("Namespace1::Namespace2::Item");
qRegisterMetaType<QVector<Namespace1::Namespace2::Item>>("QVector<Namespace1::Namespace2::Item>");

The Item by itself is a Q_GADGET :

namespace Namespace1 { namespace Namespace2 {
    class Item
    {
    Q_GADGET
        Q_PROPERTY(QString name READ getName CONSTANT)

    public:
        Item();
        Item(const QString& name);
        Item(const Item& origin);
        Item(Item&& origin);
        ~Item();

    private:
        QString _name;

    public:
        Item& operator=(const Item& rhs);
        Item& operator=(Item&& rhs);

    friend QDataStream& operator<<(QDataStream& out, const Item& item);
    friend QDataStream& operator>>(QDataStream& in, Item& item);
    friend QDebug operator<<(QDebug debug, const Item& item);
    }
} }

What am I missing? Thank you!

The "traditional" way of doing this is to convert each element to a QVariant, and pass collection as a QVariantList

QVariantList MyClass::getFooCollection(void) const
{
    QVariantList list;

    for (const auto& l: fooCollection_)
    {
        list.append(QVariant::fromValue(l));
    }

    return list;
}

The metatype system declaration and registration you have shown are required

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM