从QML访问C ++ QLists [英] Accessing C++ QLists from QML

查看:94
本文介绍了从QML访问C ++ QLists的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有一个列表的东西在C + +,我如何将它暴露给QML(在Qt5 / QtQuick 2)?看起来QML只能理解 QObject -derived类,这是一个问题,因为 QObject s不能放在 QList 中或复制。如何这样做:

  struct Thing 
{
int size;
QString name;
};

class ThingManager:public QObject
{
Q_OBJECT

//这些宏支持QtQuick,以防我们有一天想使用它slick
//接口(当QML桌面组件发布时)。
Q_PROPERTY(QList< Thing> things READ things NOTIFY thingssChanged)

public:
// ...
QList< Thing> things()const;

// ...

};所以我可以在QML中做这样的事情:

  var a = thingManager.things [0] .name; 


解决方案

有办法列出事物的方法是使用 QAbstractListModel



您可以使用 Thing ,所以它可以存储在 QVariant (注册后)。然后,您可以返回实际 Thing 作为模型项。您可以在 Repeater 中访问 model.display.a_property_of_thing 。列表长度可以使用 model.count



这有以下优点和缺点:


  1. 快速 - 它不会复制整个列表以访问一个元素。

  2. 您可以轻松获取动画


  3. 要使动画能够正常工作,每当你改变列表,你必须做一些轻微的记账( beginInsertRows()等。)

...

  class事物:public QObject 
{
...
};

Q_DECLARE_METATYPE(Thing *)

class ThingList:public QAbstractListModel
{
Q_OBJECT

public:
显式ThingList(QObject * parent = 0);
〜ThingList();

int rowCount(const QModelIndex& parent = QModelIndex())const override;
QVariant数据(const QModelIndex& index,int role = Qt :: DisplayRole)const override;

公共位置:

//额外的功能,从外面的中继器很容易得到的东西。
Thing * thing(int idx);

private:
QList< Thing *> mThings;
};

int ThingList :: rowCount(const QModelIndex& parent)const
{
return mThings.size();
}

QVariant ThingList :: data(const QModelIndex& index,int role)const
{
int i = index.row
if(i< 0 || i> = mPorts.size())
return QVariant(QVariant :: Invalid);

return QVariant :: fromValue(mThings [i]);
}

Thing * ThingList :: thing(int idx)
{
if(idx< 0 || idx> = mThings.size
return nullptr;

return mThings [idx];
}


If I've got a list of things in C++, how do I expose that to QML (in Qt5 / QtQuick 2)? It seems like QML can only understand QObject-derived classes, which is an issue because QObjects can't be put in a QList or copied. How do I do this:

struct Thing
{
    int size;
    QString name;
};

class ThingManager : public QObject
{
    Q_OBJECT

    // These macros support QtQuick, in case we one day want to use it to make a slick
    // interface (when QML desktop components are released).
    Q_PROPERTY(QList<Thing> things READ things NOTIFY thingssChanged)

public:
    // ...
    QList<Thing> things() const;

    // ...

};

So that I can do something like this in QML:?

var a = thingManager.things[0].name;

解决方案

After more experience with QML I've found the best way to have lists of things is with a QAbstractListModel.

You make your Thing derive from QObject so it can be stored in a QVariant (after registering it). Then you can return the actual Thing as the model item. You can access it in a Repeater as model.display.a_property_of_thing. The list length is available as model.count.

This has the following pros and cons:

  1. Fast - it doesn't copy the entire list to access one element.
  2. You can easily get animations for changes to the list (addition, rearrangement and removal of items).
  3. It's easy to use from QML.
  4. To enable the animations to work, whenever you change the list you have to do some slightly faffy bookkeeping (beginInsertRows() etc.)

...

class Things : public QObject
{
...
};

Q_DECLARE_METATYPE(Thing*)

class ThingList : public QAbstractListModel
{
    Q_OBJECT

public:
    explicit ThingList(QObject *parent = 0);
    ~ThingList();

    int rowCount(const QModelIndex& parent = QModelIndex()) const override;
    QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;

public slots:

    // Extra function to get the thing easily from outside Repeaters.
    Thing* thing(int idx);

private:
    QList<Thing*> mThings;
};

int ThingList::rowCount(const QModelIndex& parent) const
{
    return mThings.size();
}

QVariant ThingList::data(const QModelIndex& index, int role) const
{
    int i = index.row();
    if (i < 0 || i >= mPorts.size())
        return QVariant(QVariant::Invalid);

    return QVariant::fromValue(mThings[i]);
}

Thing* ThingList::thing(int idx)
{
    if (idx < 0 || idx >= mThings.size())
        return nullptr;

    return mThings[idx];
}

这篇关于从QML访问C ++ QLists的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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