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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QML TreeView按级别或自定义委托显示节点相关的知识,希望对你有一定的参考价值。

我有一个从QAbstractItemModel派生的树模型。我可以像树一样在树中显示数据。

enter image description here

我想要的是通过图层显示数据。一次只显示一个层的一个层并将每个层放在一个堆栈上,然后通过从堆栈中弹出该层来向后导航。 enter image description here

我想我必须实现自定义委托?任何建议都将受到高度赞赏。谢谢。

答案

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

想法是跟踪当前的QModelIndex,并使用data()rowCount()QAbstractItemModel函数来获取实际的模型数据,并使用递归堆栈视图进行导航

总体布局

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)
            }
        }

    }
}

groUp函数通过弹出项目简单地上升到堆栈

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
        }
    }

以上是关于QML TreeView按级别或自定义委托显示节点的主要内容,如果未能解决你的问题,请参考以下文章

Qml中关于TreeView 简单model自定义类型实现

Qml中关于TreeView 简单model自定义类型实现

关于c#中treeview节点的收缩与展开(.net web)

获取当前显示的委托的索引 - QML ListView

C#.NET winform treeview和panel导航效果

QML TreeView 的 C++ 模型