这段时间在写树的时候需要用到右键菜单,但是原生的不太好看,且用起来有点僵硬(不太熟悉),于是抱着手艺人的素养,就自己鼓捣了一个出来,虽然不一定非常通用,但是自己做出来的使用比较方便,后期的改动也会比较方便。
为了更方便的调用下级节点,第一级菜单使用的是Repeater,第二级使用的是listview,通过它们自身的动态创建,来实现多级菜单,而为了更方便的使用,菜单的model使用Jason来传入,所以基本思路就是解析传入的model,根据model来动态创建节点,以实现菜单的效果。
main.qml 子定义菜单的调用
import QtQuick 2.7
import QtQuick.Window 2.2
Window {
visible: true
width: 640
height: 480
title: qsTr("闻天语~")
property var model: {"七里香":["借口","外婆","将军","搁浅","乱舞春秋","困兽之斗","园游会"],
"十一月的萧邦":["夜曲","发如雪","推流","枫"],
"依然范特西":["夜的第七章","听妈妈的话","本草纲目"],
"我很忙我很忙":["牛仔很忙","彩虹","蒲公英的约定"],
"魔杰座":["稻香","蛇舞","花海","魔术先生","说好的幸福呢","兰亭序","乔克叔叔"],
"叶惠美":["晴天"," 东风破","她的睫毛"],
"八度空间":["半岛铁盒","龙拳","回到过去"],
}
color: "dimgray"
MouseArea{
anchors.fill: parent
acceptedButtons: Qt.RightButton|Qt.LeftButton
onClicked: {
if(mouse.button == Qt.RightButton)
{
menu.show(mouse.x,mouse.y)
}else{
menu.close()
}
}
}
MenuEx{
id:menu
visible: false
mainModel:model
btnHeight: 25
width: 100
x:20
y:20
}
}
MenuItemEx.qml 菜单的子项
import QtQuick 2.0
import QtQuick.Controls 1.4
Rectangle{
id:itemRoot
property variant model: []
property string showText : ""
property ExclusiveGroup exclusiveGroup:exp
property bool checked: false
onExclusiveGroupChanged: {
if (exclusiveGroup)
exclusiveGroup.bindCheckable(itemRoot)
}
height:btnHeight
color:checked?colo_c:menuRoot.color
Text {
text: showText
anchors.centerIn: parent
}
MouseArea{
id:mainMouse
anchors.fill: parent
hoverEnabled:true
onEntered:checked=true
}
Component.onCompleted:
{
for(var i in model)
{
listModel.append({"sText": model[i]})
console.log("s"+i ,model[i])
}
}
ListModel
{
id:listModel
}
Rectangle
{
anchors.left:parent.right
anchors.leftMargin: 3
height: parent.height*model.length+2*extra
width: parent.width
color: menuRoot.color
visible:itemRoot.checked
radius: extra
ListView
{
model:listModel
height: parent.height-8
width: parent.width
y:extra
id:listview
delegate:Rectangle
{
color: listview.currentIndex==index?"lightblue": childMouse.containsMouse?colo_c:menuRoot.color
Text {
x:20
anchors.verticalCenter: parent.verticalCenter
text: sText
}
height:btnHeight
width:itemRoot.width
MouseArea{
anchors.fill: parent
id:childMouse
hoverEnabled: true
onClicked: {
listview.currentIndex=index
}
}
}
}
}
}
MenuEx.qml 菜单
import QtQuick 2.0
import QtQuick.Controls 1.4
Rectangle{
id:menuRoot
color: "white"
property int btnHeight: value
property int extra: 5
property variant mainModel:[]
property variant keys : []
property string colo_c: "lightgray"
height: btnHeight*keys.length+2*extra
radius: extra
Component.onCompleted:
{
keys=Object.keys(mainModel)
for (var i in keys)
{
mainListModel.append({"btnText":keys[i]})
}
}
ExclusiveGroup{id:exp}
ListModel
{
id:mainListModel
}
ListView
{
y:extra
height: parent.height-8
model:mainListModel
width: parent.width
delegate: MenuItemEx
{
showText:btnText
model:mainModel[btnText]
width:menuRoot.width
}
}
function show(inX,inY)
{
menu.x=inX
menu.y=inY
visible=true
}
function close()
{
exp.current.checked=false
visible=false
}
}
因为只是个母本,所以真的需要什么功能可以自己去扩展,手艺人更多的是提供一个思路。因为目前是只支持两级菜单,所以以后可以拓展出多级来,和现在的思路一样,通过解析传入的Jason是否存在多级菜单,来确认是否需要再复用MenuItemEx。如果想要排序也很简单,解析出来的model在加入之前,先把解出来的列表排个序,比如第一级菜单,就可以在传入Repeater之前调用keys.sort()。暂时能想到的扩展就这些了,如果有什么好的建议或者疑问,请联系QQ995187021.