QAbstractItemModel 顶层的 QML 委托
QML delegate for top layer of QAbstractItemModel
我有一个两层 QAbstractItemModel
派生的自定义树模型,我想在 QML 中显示它。有什么方法可以为模型的每一层分配不同的代表吗?
p.s。首选解决方案意味着不更改模型
编辑:您可以假设模型看起来有点像这样:
// testmodel.h
#ifndef TESTMODEL_H
#define TESTMODEL_H
#include <QAbstractItemModel>
class TestModel : public QAbstractItemModel
{
Q_OBJECT
public:
QModelIndex index(int row, int column, const QModelIndex &parent = {}) const;
QModelIndex parent(const QModelIndex &child) const;
QModelIndex sibling(int row, int column, const QModelIndex &index) const;
int rowCount(const QModelIndex &index = {}) const;
int columnCount(const QModelIndex & = {}) const { return 1; }
QVariant data(const QModelIndex &, int) const { return {}; }
bool setData(const QModelIndex &, const QVariant &, int) { return false; }
bool insertRows(int from, int count, const QModelIndex &parent);
bool removeRows(int from, int count, const QModelIndex &parent);
private:
QVector<int> _sizes;
};
#endif // TESTMODEL_H
// testmodel.cpp
#include "testmodel.h"
constexpr uintmax_t defId = -1;
QModelIndex TestModel::index(int row, int column, const QModelIndex &parent) const {
return createIndex(row, column, parent.isValid() ? parent.row() : defId);
}
QModelIndex TestModel::parent(const QModelIndex &child) const {
auto id = child.internalId();
if (id == defId)
return {};
return createIndex(id, 0, defId);
}
QModelIndex TestModel::sibling(int row, int column, const QModelIndex &index) const {
if (!index.isValid())
return {};
return createIndex(row, column, index.internalId());
}
int TestModel::rowCount(const QModelIndex &index) const {
if (!index.isValid())
return _sizes.size();
if (index.internalId() != defId)
return 0;
int row = index.row();
return row >= _sizes.size() ? 0 : _sizes[index.row()];
}
bool TestModel::insertRows(int from, int count, const QModelIndex &parent) {
if (count <= 0 || from < 0)
return false;
auto to = from + count - 1;
if (!parent.isValid()) {
if (from > _sizes.size())
return false;
beginInsertRows(parent, from, to);
_sizes.insert(from, count, 0);
endInsertRows();
return true;
}
if (parent.internalId() != defId)
return false;
int row = parent.row();
if (row >= _sizes.size())
return false;
if (from > _sizes[row])
return false;
beginInsertRows(parent, from, to);
_sizes[row] += count;
endInsertRows();
return true;
}
bool TestModel::removeRows(int from, int count, const QModelIndex &parent) {
if (count <= 0 || from < 0)
return false;
auto to = from + count - 1;
if (!parent.isValid()) {
if (to >= _sizes.size())
return false;
beginRemoveRows(parent, from, to);
_sizes.remove(from, count);
endRemoveRows();
return true;
}
if (parent.internalId() != defId)
return false;
int row = parent.row();
if (row >= _sizes.size())
return false;
if (to >= _sizes[row])
return false;
beginRemoveRows(parent, from, to);
_sizes[row] -= count;
endRemoveRows();
return true;
}
我实际上是在寻找 DelegateModel
组件(或 VisualDataModel
)。列出一个简单示例,将模型的顶层显示为红色行,由底层的蓝色矩形填充:
ListView {
id: view
anchors.fill: parent
model: DelegateModel {
model: testModel // testModel is a tree model as context property
delegate: Rectangle {
width: win.width
height: 30
color: "red"
border.color: "black"
ListView {
anchors.fill: parent
orientation: Qt.Horizontal
model: DelegateModel {
model: testModel
rootIndex: view.model.modelIndex(index, 0)
delegate: Rectangle {
height: 30
width: height
color: "blue"
border.color: "black"
}
}
}
}
}
}
我有一个两层 QAbstractItemModel
派生的自定义树模型,我想在 QML 中显示它。有什么方法可以为模型的每一层分配不同的代表吗?
p.s。首选解决方案意味着不更改模型
编辑:您可以假设模型看起来有点像这样:
// testmodel.h
#ifndef TESTMODEL_H
#define TESTMODEL_H
#include <QAbstractItemModel>
class TestModel : public QAbstractItemModel
{
Q_OBJECT
public:
QModelIndex index(int row, int column, const QModelIndex &parent = {}) const;
QModelIndex parent(const QModelIndex &child) const;
QModelIndex sibling(int row, int column, const QModelIndex &index) const;
int rowCount(const QModelIndex &index = {}) const;
int columnCount(const QModelIndex & = {}) const { return 1; }
QVariant data(const QModelIndex &, int) const { return {}; }
bool setData(const QModelIndex &, const QVariant &, int) { return false; }
bool insertRows(int from, int count, const QModelIndex &parent);
bool removeRows(int from, int count, const QModelIndex &parent);
private:
QVector<int> _sizes;
};
#endif // TESTMODEL_H
// testmodel.cpp
#include "testmodel.h"
constexpr uintmax_t defId = -1;
QModelIndex TestModel::index(int row, int column, const QModelIndex &parent) const {
return createIndex(row, column, parent.isValid() ? parent.row() : defId);
}
QModelIndex TestModel::parent(const QModelIndex &child) const {
auto id = child.internalId();
if (id == defId)
return {};
return createIndex(id, 0, defId);
}
QModelIndex TestModel::sibling(int row, int column, const QModelIndex &index) const {
if (!index.isValid())
return {};
return createIndex(row, column, index.internalId());
}
int TestModel::rowCount(const QModelIndex &index) const {
if (!index.isValid())
return _sizes.size();
if (index.internalId() != defId)
return 0;
int row = index.row();
return row >= _sizes.size() ? 0 : _sizes[index.row()];
}
bool TestModel::insertRows(int from, int count, const QModelIndex &parent) {
if (count <= 0 || from < 0)
return false;
auto to = from + count - 1;
if (!parent.isValid()) {
if (from > _sizes.size())
return false;
beginInsertRows(parent, from, to);
_sizes.insert(from, count, 0);
endInsertRows();
return true;
}
if (parent.internalId() != defId)
return false;
int row = parent.row();
if (row >= _sizes.size())
return false;
if (from > _sizes[row])
return false;
beginInsertRows(parent, from, to);
_sizes[row] += count;
endInsertRows();
return true;
}
bool TestModel::removeRows(int from, int count, const QModelIndex &parent) {
if (count <= 0 || from < 0)
return false;
auto to = from + count - 1;
if (!parent.isValid()) {
if (to >= _sizes.size())
return false;
beginRemoveRows(parent, from, to);
_sizes.remove(from, count);
endRemoveRows();
return true;
}
if (parent.internalId() != defId)
return false;
int row = parent.row();
if (row >= _sizes.size())
return false;
if (to >= _sizes[row])
return false;
beginRemoveRows(parent, from, to);
_sizes[row] -= count;
endRemoveRows();
return true;
}
我实际上是在寻找 DelegateModel
组件(或 VisualDataModel
)。列出一个简单示例,将模型的顶层显示为红色行,由底层的蓝色矩形填充:
ListView {
id: view
anchors.fill: parent
model: DelegateModel {
model: testModel // testModel is a tree model as context property
delegate: Rectangle {
width: win.width
height: 30
color: "red"
border.color: "black"
ListView {
anchors.fill: parent
orientation: Qt.Horizontal
model: DelegateModel {
model: testModel
rootIndex: view.model.modelIndex(index, 0)
delegate: Rectangle {
height: 30
width: height
color: "blue"
border.color: "black"
}
}
}
}
}
}