QML TreeView 按级别或自定义委托显示节点
QML TreeView display nodes by levels or custom delegate
我有一个派生自 QAbstractItemModel 的树模型。而且我可以像树一样显示数据。
我想要的是按层显示数据。一次只显示一个图层的一个级别并将每个图层放在堆栈上并通过从堆栈中弹出图层来向后导航。
我想我必须实现自定义委托?任何建议将不胜感激。谢谢。
我最近实现了类似的东西,基于 QFileSystemModel
,设置为 qml contextProperty,在下面的示例中命名为 treeModel。
想法是跟踪当前 QModelIndex
,并使用 QAbstractItemModel
的 data()
和 rowCount()
函数来获取实际模型数据,并使用递归堆栈视图进行导航
总体布局
ApplicationWindow {
id: main
visible: true
width: 640
height: 480
ColumnLayout
{
anchors.fill: parent
// Breadcrumb
SEE BELOW
// View
StackView
{
id: stackView
Layout.fillHeight: true
Layout.fillWidth: true
initialItem: TreeSlide {}
}
}
}
TreeSlide
视图本身非常简单。我在这里没有使用任何花哨的东西,它只显示一个角色,但你可以毫不费力地扩展它。请注意,视图的模型不是您的 treeModel,而只是 rootIndex 的 rowCount。
ListView
{
Layout.fillHeight: true
Layout.fillWidth: true
model: treeModel.rowCount(rootIndex)
clip: true
snapMode: ListView.SnapToItem
property var rootIndex
// I used a QFileSytemModel in my example, so I had to manually
// fetch data when the rootIndex changed. You may not need this though.
onRootIndexChanged: {
if(treeModel.canFetchMore(rootIndex))
treeModel.fetchMore(rootIndex)
}
Connections {
target: treeModel
onRowsInserted: {
rootIndexChanged()
}
}
delegate: ItemDelegate {
property var modelIndex: treeModel.index(index,0, rootIndex)
property bool hasChildren: treeModel.hasChildren(modelIndex)
width: parent.width
text: treeModel.data(modelIndex)
onClicked: {
if(hasChildren)
{
// Recursively add another TreeSlide, with a new rootIndex
stackView.push("TreeSlide.qml", {rootIndex: modelIndex})
}
}
}
}
面包屑
为了导航模型,我使用了一种动态面包屑而不是简单的后退按钮
// Breadcrumb
RowLayout
{
Repeater
{
id: repeat
model: {
var res = []
var temp = stackView.currentItem.rootIndex
while(treeModel.data(temp) != undefined)
{
res.unshift(treeModel.data(temp))
temp = temp.parent
}
res.unshift('.')
return res
}
ItemDelegate
{
text : modelData
onClicked: {
goUp(repeat.count - index-1)
}
}
}
}
goUp 函数只是通过弹出项目在堆栈中上升
function goUp(n)
{
for(var i=0; i<n; i++)
stackView.pop()
}
要完全由指南完成,我们应该使用 DelegateModel
和 DelegateModel.rootIndex
DelegateModel {
id: delegateSupportPropConfigModel
model: supportModel
delegate: SupportPropConfigListItem {
id: currentItem
width: scrollRect2.width - 60
fieldName: model.fieldName
fieldValue: model.value
onClick:{
delegateSupportPropConfigModel.rootIndex = supportPropConfigModel.index(0, 0, supportPropConfigModel)
}
}
}
Column {
id: columnSettings
spacing: 2
Repeater {
model: delegateSupportPropConfigModel
}
}
我有一个派生自 QAbstractItemModel 的树模型。而且我可以像树一样显示数据。
我想要的是按层显示数据。一次只显示一个图层的一个级别并将每个图层放在堆栈上并通过从堆栈中弹出图层来向后导航。
我想我必须实现自定义委托?任何建议将不胜感激。谢谢。
我最近实现了类似的东西,基于 QFileSystemModel
,设置为 qml contextProperty,在下面的示例中命名为 treeModel。
想法是跟踪当前 QModelIndex
,并使用 QAbstractItemModel
的 data()
和 rowCount()
函数来获取实际模型数据,并使用递归堆栈视图进行导航
总体布局
ApplicationWindow {
id: main
visible: true
width: 640
height: 480
ColumnLayout
{
anchors.fill: parent
// Breadcrumb
SEE BELOW
// View
StackView
{
id: stackView
Layout.fillHeight: true
Layout.fillWidth: true
initialItem: TreeSlide {}
}
}
}
TreeSlide
视图本身非常简单。我在这里没有使用任何花哨的东西,它只显示一个角色,但你可以毫不费力地扩展它。请注意,视图的模型不是您的 treeModel,而只是 rootIndex 的 rowCount。
ListView
{
Layout.fillHeight: true
Layout.fillWidth: true
model: treeModel.rowCount(rootIndex)
clip: true
snapMode: ListView.SnapToItem
property var rootIndex
// I used a QFileSytemModel in my example, so I had to manually
// fetch data when the rootIndex changed. You may not need this though.
onRootIndexChanged: {
if(treeModel.canFetchMore(rootIndex))
treeModel.fetchMore(rootIndex)
}
Connections {
target: treeModel
onRowsInserted: {
rootIndexChanged()
}
}
delegate: ItemDelegate {
property var modelIndex: treeModel.index(index,0, rootIndex)
property bool hasChildren: treeModel.hasChildren(modelIndex)
width: parent.width
text: treeModel.data(modelIndex)
onClicked: {
if(hasChildren)
{
// Recursively add another TreeSlide, with a new rootIndex
stackView.push("TreeSlide.qml", {rootIndex: modelIndex})
}
}
}
}
面包屑
为了导航模型,我使用了一种动态面包屑而不是简单的后退按钮
// Breadcrumb
RowLayout
{
Repeater
{
id: repeat
model: {
var res = []
var temp = stackView.currentItem.rootIndex
while(treeModel.data(temp) != undefined)
{
res.unshift(treeModel.data(temp))
temp = temp.parent
}
res.unshift('.')
return res
}
ItemDelegate
{
text : modelData
onClicked: {
goUp(repeat.count - index-1)
}
}
}
}
goUp 函数只是通过弹出项目在堆栈中上升
function goUp(n)
{
for(var i=0; i<n; i++)
stackView.pop()
}
要完全由指南完成,我们应该使用 DelegateModel
和 DelegateModel.rootIndex
DelegateModel {
id: delegateSupportPropConfigModel
model: supportModel
delegate: SupportPropConfigListItem {
id: currentItem
width: scrollRect2.width - 60
fieldName: model.fieldName
fieldValue: model.value
onClick:{
delegateSupportPropConfigModel.rootIndex = supportPropConfigModel.index(0, 0, supportPropConfigModel)
}
}
}
Column {
id: columnSettings
spacing: 2
Repeater {
model: delegateSupportPropConfigModel
}
}