以下代码来自Qt演示。这是QTreeView的模型。
下面的 TreeItem
类表示树中的每个节点,它可以有子节点。
class TreeItem
{
public:
explicit TreeItem(const QList<QVariant> &data, TreeItem *parentItem = 0);
~TreeItem();
void appendChild(TreeItem *child);
TreeItem *child(int row);
int childCount() const;
int columnCount() const;
QVariant data(int column) const;
int row() const;
TreeItem *parentItem();
private:
QList<TreeItem*> m_childItems;
QList<QVariant> m_itemData;
TreeItem *m_parentItem;
};
下面的 TreeModel
类是主要模型。它只包含一个包含所有其他子节点的根节点。
class TreeModel : public QAbstractItemModel
{
Q_OBJECT
public:
explicit TreeModel(const QString &data, QObject *parent = 0);
~TreeModel();
QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE;
Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE;
QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
QModelIndex index(int row, int column,
const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
QModelIndex parent(const QModelIndex &index) const Q_DECL_OVERRIDE;
int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
private:
void setupModelData(const QStringList &lines, TreeItem *parent);
TreeItem *rootItem;
};
我正在使用QML,我可以在树中显示此模型,但我也希望以ListView
显示。
对于ListView,我只想一次显示一个层(第一个孩子)。当用户点击任何一个项目时,它应该清除并显示该项目的子项。我该怎么做?
我的Qml代码如下。它显示所有第一层孩子,这很棒,但我需要在用户点击某个项目时显示孩子。我的想法是需要提取子模型并指向它,但是如何?
Item {
width: parent.width
height: parent.height
ListView {
//anchors.top: myImage.bottom
anchors.fill: parent
id: list
spacing: 4
model: treeModel
delegate: listDelegate
}
Component {
id: listDelegate
Rectangle
{
id: delegateRect
height: image.height
width: 500
Image {
id: image
source: "qrc:/icons/resources/element.ico"
}
Text {
id: t
anchors.left: image.right
anchors.leftMargin: 20
anchors.centerIn: delegateRect
text: title + "/" + summary
//text: display
}
MouseArea {
anchors.fill: parent
onClicked: {
list.currentIndex = index
console.log("Item clicked, index = " + index)
// I think I should change model here to sub model but how do I do it?
//list.model = treeModel.data(index)
}
}
}
}
}
答案 0 :(得分:1)
您应该查看Qt文档http://doc.qt.io/qt-5/qabstractproxymodel.html中的QAbstractProxyModel和派生类。
代理模型用于映射模型索引(如果要修改布局,或对数据进行排序/过滤)并进行数据处理(修改源模型数据方法返回的数据)。
您需要做的是添加一个属性来选择 new root (应该是提取模型的根项的项)并实现两个方法mapFromSource(const QModelIndex &)
和mapToSource(const QModelIndex &)
。这些方法将给予视图的模型索引(仅在代理模型中有效)映射到基于当前设置的 root 属性对源模型有效的模型索引(反之亦然)。
此外,您还应重新实现roleNames()
方法,以转发源模型定义的角色名,以便能够从QML内部访问数据。