QML TreeView 按级别或自定义委托显示节点

QML TreeView display nodes by levels or custom delegate

我有一个派生自 QAbstractItemModel 的树模型。而且我可以像树一样显示数据。

我想要的是按层显示数据。一次只显示一个图层的一个级别并将每个图层放在堆栈上并通过从堆栈中弹出图层来向后导航。

我想我必须实现自定义委托?任何建议将不胜感激。谢谢。

我最近实现了类似的东西,基于 QFileSystemModel,设置为 qml contextProperty,在下面的示例中命名为 treeModel。

想法是跟踪当前 QModelIndex,并使用 QAbstractItemModeldata()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()
}

要完全由指南完成,我们应该使用 DelegateModelDelegateModel.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
        }
    }