[英]How to expose list of custom objects with Q_PROPERTY
我有一个非常简单的类,具有2个属性; 关键和价值:
KeyValue.h:
class KeyValue : public QObject
{
Q_OBJECT
Q_PROPERTY(QString key READ getKey WRITE setKey NOTIFY keyChanged)
Q_PROPERTY(QString value READ getValue WRITE setValue NOTIFY valueChanged)
public:
KeyValue(const QString& key, const QString& value, QObject* parent = 0);
signals:
void keyChanged();
void valueChanged();
private:
QString _key;
QString _value;
QString getKey() const;
QString getValue() const;
void setKey(const QString& key);
void setValue(const QString& value);
};
Q_DECLARE_METATYPE(KeyValue)
在另一个类中,我想要一个包含KeyValue对象列表的属性,因此我可以将此列表用作QML中的模型。
控制器
class Controller : public QObject
{
Q_OBJECT
Q_PROPERTY(QList<KeyValue*> items READ getItems NOTIFY itemsChanged)
public:
explicit Controller(QObject* parent = 0);
signals:
void itemsChanged();
private:
QList<KeyValue*> getItems() const;
};
我希望能够通过以下方式在QML中使用它:
import QtQuick 2.7
import customqml 1.0
Item{
Controller{
id: controller
}
Repeater{
model: controller.items
Text{
text: modelData.key + ": " + modelData.value
}
}
}
这两个类都在我的main.cpp文件中注册:
qmlRegisterType<KeyValue>("customqml", 1, 0, "KeyValue");
qmlRegisterType<Controller>("customqml", 1, 0, "Controller");
上面的代码不起作用,因为我显然无法直接将QList公开给QML。 我曾尝试使用QAbstractItemModel和QQmlListProperty,但无法使其正常工作。 谁能指出我正确的方向?
我的主要问题是Controller类中items属性的类型以及getItems方法的返回值。
如果这有任何区别,我正在使用Qt 5.9。
注意:
吸气剂和吸气剂通常是公共的,除了例外,因此将其移到公共部分
从QObject继承的类不需要QMetaType,因为当您要传输该类的数据时,将使用指针。
QML通过Q_PROPERTY并非所有数据类型都支持,因此一种可能的解决方案是通过诸如
QList<QObject *>
: class Controller : public QObject
{
Q_OBJECT
Q_PROPERTY(QList<QObject *> items READ getItems NOTIFY itemsChanged)
public:
explicit Controller(QObject *parent = nullptr);
QList<QObject *> getItems() const;
signals:
void itemsChanged();
private:
QList<KeyValue *>key_values_list;
};
...
QList<QObject *> Controller::getItems() const
{
QObjectList l;
for(auto e: key_values_list)
l << e;
return l;
}
QVariantList
: class Controller : public QObject
{
Q_OBJECT
Q_PROPERTY(QVariantList items READ getItems NOTIFY itemsChanged)
public:
explicit Controller(QObject *parent = nullptr);
QVariantList getItems() const;
signals:
void itemsChanged();
private:
QList<KeyValue *>key_values_list;
};
...
QVariantList Controller::getItems() const
{
QVariantList l;
for(auto e: key_values_list)
l.append(QVariant::fromValue(e));
return l;
}
其他选项是实现模型,下面的示例仅显示只读模型:
键值模型
#ifndef KEYVALUEMODEL_H
#define KEYVALUEMODEL_H
#include "keyvalue.h"
#include <QAbstractListModel>
class KeyValueModel : public QAbstractListModel
{
Q_OBJECT
public:
explicit KeyValueModel(QObject *parent = nullptr)
: QAbstractListModel(parent)
{
key_values_list = {new KeyValue{"k", "v"}, new KeyValue{"k2", "v2"}};
}
int rowCount(const QModelIndex &parent = QModelIndex()) const override
{
if (parent.isValid())
return 0;
return key_values_list.length();
}
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
{
if (!index.isValid())
return QVariant();
if(index.row() >= 0 && index.row() < rowCount())
return QVariant::fromValue(key_values_list[index.row()]);
return QVariant();
}
private:
QList<KeyValue* >key_values_list;
};
#endif // KEYVALUEMODEL_H
class Controller : public QObject
{
Q_OBJECT
Q_PROPERTY(KeyValueModel* items READ getItems NOTIFY itemsChanged)
public:
explicit Controller(QObject *parent = nullptr);
KeyValueModel* getItems() const;
signals:
void itemsChanged();
private:
KeyValueModel *model;
};
...
Text{
text: display.key + ": " + display.value
}
...
并且以类似的方式可以实现QQmlListProperty,在文档中有很多示例。
如果您想要一个具有添加/删除对象和更改数据的复杂模型,则应考虑对QAbstractListModel进行子类化。
作为一种简单但不太灵活的方法,您可以使用QVariantList并使Controller类成为值类型。 你需要:
Q_PROPERTY类型和返回值就是QVariantList。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.