从 QML 访问 C++ QLists
如果我有 C++ 中的内容列表,如何将其公开给 QML(在 Qt5/QtQuick 2 中)?似乎 QML 只能理解 QObject
派生类,这是一个问题,因为 QObject
不能放入 QList
或复制.我该怎么做:
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 QObject
s 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;
// ...
};
这样我就可以在 QML 中做这样的事情:?
So that I can do something like this in QML:?
var a = thingManager.things[0].name;
推荐答案
在获得更多 QML 经验后,我发现拥有事物列表的最佳方式是使用 QAbstractListModel
.
After more experience with QML I've found the best way to have lists of things is with a QAbstractListModel
.
您使您的 Thing
从 QObject
派生,因此它可以存储在 QVariant
中(在注册之后).然后您可以将实际的 Thing
作为模型项返回.您可以在 Repeater
中以 model.display.a_property_of_thing
的形式访问它.列表长度以 model.count
的形式提供.
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
.
这有以下优点和缺点:
- 快速 - 它不会复制整个列表来访问一个元素.
- 您可以轻松获取列表更改的动画(添加、重新排列和删除项目).
- 在 QML 中很容易使用.
- 为了使动画能够正常工作,每当您更改列表时,您都必须做一些稍微有点古怪的簿记(
beginInsertRows()
等)
...
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 >= mThings.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];
}
相关文章