带有 QAbstractItemModel 的 QML ComboBox
我正在实现一个基于 QAbstractItemModel 的简单列表模型:
class BaseListModel : public QAbstractListModel
{
Q_OBJECT
Q_DISABLE_COPY(BaseListModel)
Q_PROPERTY(int length READ getCount NOTIFY countChanged)
protected:
enum Roles{
ModelDataRole = Qt::UserRole+1
};
public:
explicit BaseListModel(QObject* parent = nullptr);
virtual ~BaseListModel();
virtual int getCount() const { return _data.size(); }
Q_INVOKABLE virtual QVariant at(int index) const;
/*
functions: add(), remove(), ...
*/
public: // QAbstractListModel
QHash<int, QByteArray> roleNames() const override {
QHash<int, QByteArray> roles;
roles[ModelDataRole] = "modelData";
return roles;
}
signals:
void countChanged();
};
在 QML 代码上,我可以使用一个简单的列表,调用 count 或 length 来获取内容大小,并调用 at(index) 来获取条目。 我使用单个角色“modelData”来符合文档:
有关模型的 Qt 文档:
没有命名角色的模型(例如所示的 ListModel) 下面)将通过 modelData 角色提供数据。这 modelData 角色还为只有一个角色的模型提供。在 在这种情况下,modelData 角色包含与指定角色相同的数据。
注意:如果以下情况,模型、索引和 modelData 角色将无法访问 delegate 包含必需的属性,除非它还需要 具有匹配名称的属性。
对于中继器或其他委托成员来说,使用它很容易:
AnyView {
...
model: my_model
delegate: Text {
text: modelData.description
}
..
}
现在,为了让组合框显示说明,我尝试设置 textRole:
ComboBox {
...
model: my_model
textRole: "description"
...
}
但没有任何反应......组合框仍然为空。
我使用 modelData.description 实现一个新的委托(与原始委托不太正确)以在弹出列表中显示文本,但是当弹出窗口关闭时(在我选择一个条目之后),组合框仍为空。
有人知道我做错了什么吗?
重要的是:这里我试图实现的是共享从 C++ 到 QML 的通用数据列表。该模型包含 C++ 中的列表,无需创建另一个列表,并且可以在模型中使用。
template <class T>
class SimpleListModel : public BaseListModel
{
public:
explicit SimpleListModel(QObject* parent = nullptr);
SimpleListModel(const QList<T>& initList, QObject* parent = nullptr);
int getCount() const override;
QVariant at(int index) const override;
public:
void append(T item);
void insert(int index, T item);
bool remove(T item);
void removeAt(int index);
void swapAt(int first_index, int second_index);
const QList<T>& getList() const;
public: // QAbstractItemModel interface
int rowCount(const QModelIndex &parent) const override;
QVariant data(const QModelIndex &index, int role) const override;
private: // finally the list
QList<T> m_data;
};
I'm implementing a simple list model, based on QAbstractItemModel:
class BaseListModel : public QAbstractListModel
{
Q_OBJECT
Q_DISABLE_COPY(BaseListModel)
Q_PROPERTY(int length READ getCount NOTIFY countChanged)
protected:
enum Roles{
ModelDataRole = Qt::UserRole+1
};
public:
explicit BaseListModel(QObject* parent = nullptr);
virtual ~BaseListModel();
virtual int getCount() const { return _data.size(); }
Q_INVOKABLE virtual QVariant at(int index) const;
/*
functions: add(), remove(), ...
*/
public: // QAbstractListModel
QHash<int, QByteArray> roleNames() const override {
QHash<int, QByteArray> roles;
roles[ModelDataRole] = "modelData";
return roles;
}
signals:
void countChanged();
};
On QML code I could use a simple list, calling count or length for the content size and at(index) for an entry.
I'm using a single Role "modelData" to be compliant with the documentation:
Qt documentation on models:
Models that do not have named roles (such as the ListModel shown
below) will have the data provided via the modelData role. The
modelData role is also provided for models that have only one role. In
this case the modelData role contains the same data as the named role.Note: model, index, and modelData roles are not accessible if the
delegate contains required properties, unless it has also required
properties with matching names.
For repeater or another delegate member it's easy to use it:
AnyView {
...
model: my_model
delegate: Text {
text: modelData.description
}
..
}
Now for the ComboBox to make it showing to the description, I try to set the textRole:
ComboBox {
...
model: my_model
textRole: "description"
...
}
But nothing happens ... the combobox remains empty.
I implement a new delegate (not so correct as of the original) using the modelData.description to show text in the popup list, but when the popup closes (after I select an entry) the combobox remains empty.
Has somebody an idea about what I do wrongly?
Something important: here what I try to achieve is to share a generic list of data from c++ up to QML. The model contains the list in C++ no need to create another one and is usable in the model.
template <class T>
class SimpleListModel : public BaseListModel
{
public:
explicit SimpleListModel(QObject* parent = nullptr);
SimpleListModel(const QList<T>& initList, QObject* parent = nullptr);
int getCount() const override;
QVariant at(int index) const override;
public:
void append(T item);
void insert(int index, T item);
bool remove(T item);
void removeAt(int index);
void swapAt(int first_index, int second_index);
const QList<T>& getList() const;
public: // QAbstractItemModel interface
int rowCount(const QModelIndex &parent) const override;
QVariant data(const QModelIndex &index, int role) const override;
private: // finally the list
QList<T> m_data;
};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论