【问题标题】:How to pass QVector<Custom_Q_GADGET> to QML?如何将 QVector<Custom_Q_GADGET> 传递给 QML?
【发布时间】:2020-02-05 14:44:34
【问题描述】:

我有具有 2 个属性的 QObject 类:

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;
}

QML 中的 QVectorQStrings 一切正常,但我无法通过 Namespace1::Namespace2::Items 中的 QVector

QML 控制台的输出给了我: QVariant(​QVector&lt;Namespace1::Namespace2:​Item&gt;)​ 用于 console.log(foo.items) 和 length = undefined 用于 console.log(foo.items.length)

我从 Qt 文档中发现的:

这些序列类型是根据底层 C++ 序列直接实现的。有两种方式可以将此类序列暴露给 QML: 作为给定序列类型的 Q_PROPERTY;或作为 Q_INVOKABLE 方法的返回类型。

...

具体来说,QML 目前支持: ... QList... 以及所有已注册的 QList、QVector、QQueue、QStack、QSet、QLinkedList、std::list、std::vector 包含标记为的类型Q_DECLARE_METATYPE。

据我了解,一切都归结为:

Q_DECLARE_METATYPE(Namespace1::Namespace2::Item)

除此之外:

有些类型是自动注册的,不需要这个宏:指向从QObject、QListQVector、QQueue、QStack、QSet派生的类的指针 或 QLinkedList,其中 T 是已注册的元类型

但是,我也尝试声明元类型(显然没有运气):

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

并且还尝试注册元类型(也没有任何运气):

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

Item 本身就是一个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);
    }
} }

我错过了什么? 谢谢!

【问题讨论】:

  • 您是否尝试过使用指针:QVector&lt;ns1::ns2::item*&gt;?我意识到我经常采用QList&lt;QObject*&gt; 的方式......并不理想,但它可以工作,因为我正在使用 QML。
  • @Amfasis 感谢您的回复。是的,我不时在 QML 中使用指针,但在这种情况下不是。此外,我必须关心所有权,因为我需要一份副本。
  • 我花了一些时间试图让这个工作,但不能真正......我认为你应该考虑QQmlListProperty,你也可以将其设为只读,或QAbstractListModel。所有权是什么意思?
  • @Amfasis 谢谢你的努力,我也有同样的负面结果。最后,按照您的建议使用 QML List Property 重新实现。顺便说一句,你觉得我应该在 bugreports.qt.io 上报告一个错误吗?
  • 似乎已经有一些报道:bugreports.qt.io/browse/QTBUG-73399,我觉得他们将推迟到 Qt 6

标签: c++ qt qml


【解决方案1】:

执行此操作的“传统”方式是将每个元素转换为 QVariant,并将集合作为 QVariantList 传递

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

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

    return list;
}

您展示的元类型系统声明和注册是必需的

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-18
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 2019-10-12
    • 1970-01-01
    相关资源
    最近更新 更多