【问题标题】:QML: Multi-level Menu from ListModelQML:来自 ListModel 的多级菜单
【发布时间】:2020-09-08 13:30:54
【问题描述】:

我有一个多级 ListModel 示例:

ListModel{
    id: myModel
    ListElement{
        name: "File"
        subItems:[
            ListElement{
                name: "Open"
            },
            ListElement{
                name: "Open Recent"
                subItems:[
                    ListElement{
                        name: "Bla.txt"
                    }
                ]
            },
            ListElement{
                name: "Save"
            },
            ListElement{
                name: "Save as"
            },
            ListElement{
                name: "Exit"
            }
        ]
    }
    ListElement{
        name: "Edit"
        subItems:[
            ListElement{
                name: "Undo"
            },
            ListElement{
                name: "Redo"
            },
            ListElement{
                name: "Select All"
            }
        ]
    }
    ListElement{
        name: "Help"
        subItems:[
            ListElement{
                name: "About"
            }
        ]
    }
}

我想显示为菜单。从here 我知道如何在 Menu 组件内迭代模型。但是因为我有多级结构,所以我应该检查第二级是 Menu 还是 MenuItem。因此我使用 Loader 并选择要加载的组件(检查元素的subItems 是否为undefined):

    MenuBar{
    id: menuBar
    Instantiator{
        id: menuBarRepeater
        model: myModel
        onObjectRemoved: menuBar.removeItem( object )
        delegate: Loader{
            sourceComponent: myModel.get(index)["subItems"]? subMenuLoader : menuItemLoader
            onLoaded: {
                item.name = model.name;
                if(myModel.get(index)["subItems"]){
                    item.parentIndex = index;
                    item.model = model
                    menuBar.insertMenu( index, item )
                }else{
                    menuBar.insertItem( index, item )
                }
            }
        }
    }
}

最后,我需要为第三级菜单再添加一个 Instantiator。我可以递归地做到这一点,但例如我会假设我有最大值。 3个级别。所以上面代码中要加载的组件有:

    Component{
    id: menuItemLoader
    MenuItem{
        property var name
        text: name
    }
}

Component{
    id: subMenuLoader
    Menu{
        id: subMenu
        property var name
        property var parentIndex: index
        property var model
        title: name
        Instantiator{
            model: model
            onObjectRemoved: menuBar.removeItem( object )
            delegate: Loader{
                sourceComponent: myModel.get(parentIndex)["subItems"].get(index)["subItems"] ? subMenuLoader : menuItemLoader
                onLoaded: {
                    item.name = model.name;
                    if(myModel.get(parentIndex)["subItems"].get(index)["subItems"]){
                        subMenu.insertMenu( index, item )
                    }else{
                        subMenu.insertItem( index, item )
                    }
                }
            }
        }
    }
}

我的问题是,将传递到第二级的模型是QQmlDMListAccessorData,并且不可迭代。有没有办法获得 Intantiator 模型项的子项?

【问题讨论】:

  • 等等,你的标题是指多级菜单,你提供了大量的代码来描述你的多级结构,但你的问题只是关于获取 Instantiator 的子级?
  • 菜单也应该是多级的,这会导致 Instantiator 和获取其子级的问题。但我也愿意了解如何从多级结构动态构建多级菜单
  • 你试过 Instantiator 的objectAt 方法吗?
  • 是的,menuBarRepeater.objectAt(index) 返回null

标签: qt qml


【解决方案1】:

所以,我找到的解决方法是:我使用myModel.get(parentIndex)["subItems"].get(index),而不是将模型(类型为QQmlDMListAccessorData)传递给subMenu,而是作为第二级Instantiator 模型,它的地址是@987654325 @,对于 QML,其类型为 QQmlListModel(%index%),可以完全用作其父级(myModel 本身)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多