从QML访问C ++ QLists [英] Accessing C++ QLists from QML
问题描述
如果我有一个列表的东西在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
。
这有以下优点和缺点:
- 快速 - 它不会复制整个列表以访问一个元素。
- 您可以轻松获取动画
- 要使动画能够正常工作,每当你改变列表,你必须做一些轻微的记账(
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 becauseQObject
s can't be put in aQList
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 fromQObject
so it can be stored in aQVariant
(after registering it). Then you can return the actualThing
as the model item. You can access it in aRepeater
asmodel.display.a_property_of_thing
. The list length is available asmodel.count
.This has the following pros and cons:
- Fast - it doesn't copy the entire list to access one element.
- You can easily get animations for changes to the list (addition, rearrangement and removal of items).
- It's easy to use from QML.
- 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屋!