qt5 中本身提供了扇形菜单 piemenu,属于 qtquick.extras 模块,这个模块是拓展自 qtquick.control1 的,qtquick.control1 在 qt5 高版本被废弃,并在 qt6 移除。
不过我们也可以用 qtquick.control2 的组件自定义样式来实现环形或扇形的菜单和选择框。主要思路就是使用 pathview 来替换默认的 listview,再改下弹框的背景样式。
itemdelegate 需要设置给 combobox 或者 menu,而不是 view。最好用 button 的相关类型(默认是 itemdelegate 类型),因为组件默认这些小部件是 button 类型,内部 cast 成按钮来处理的。而且用按钮就不用自己处理下拉框 currentindex,内部会自己处理,这也避免了我们在这个 delegate 对 currentindex 赋值后导致其属性绑定失效的问题。
qquickaction *qquickmenu::actionat(int index) const { q_d(const qquickmenu); qquickabstractbutton *item = qobject_cast<qquickabstractbutton *>(d->itemat(index)); if (!item) return nullptr; return item->action(); }
自定义的时候遇到一点状况,就是 pathview 替代 listview 作为 menu 的 contentitem 后,menu 的 contentdata 和 contentmodel 始终会多一个表示高亮的 item,这样环形路径就有个缺口,目前我只能将显示的 item 个数减去一个来使显示效果正常。
contentitem: pathview { model: control.contentmodel //把pathview放menu,会有一个高亮item被放到contentmodel,减去 pathitemcount: control.count > 0 ? control.count - 1 : 0 //... ... }
demo 链接:https://github.com/gongjianbo/mytestcode2021/tree/master/qml/testqml_20220313_pathview
主要代码:
import qtquick 2.12 import qtquick.window 2.12 import qtquick.controls 2.12 window { width: 640 height: 480 visible: true title: qstr("pathview") row { anchors.centerin: parent spacing: 20 mycombobox { model: 10 } button { width: 60 height: 30 text: "menu" background: rectangle { radius: 15 color: "red" border.color: "black" } onclicked: { menu.popup() } mymenu { id: menu anchors.centerin: parent action { text: "1" } action { text: "2" } action { text: "3" } action { text: "4" } action { text: "5" } action { text: "6" } action { text: "7" } action { text: "8" } action { text: "9" } action { text: "10" } } } } }
import qtquick 2.12 import qtquick.controls 2.12 //环形选择框 //龚建波 2022-03-13 //note:弹框为pop会被限制在window内 combobox { id: control implicitwidth: 30 implicitheight: 30 opacity: 0.9999 delegate: itemdelegate { width: 30 height: width padding: 0 background: rectangle { radius: width / 2 color: "green" border.color: "black" } contentitem: text { text: modeldata padding: 0 verticalalignment: text.alignvcenter horizontalalignment: text.alignhcenter } } contentitem: text { text: control.displaytext padding: 0 verticalalignment: text.alignvcenter horizontalalignment: text.alignhcenter } indicator: null background: rectangle { radius: 15 color: "green" border.color: "black" } popup: popup { id: pop width: 200 height: width anchors.centerin: parent margins: 0 padding: 0 //pathview环形的角度范围和延申半径 property int angle: 1 property int spread: 1 //pop弹出和隐藏时的过渡动画 enter: transition { parallelanimation { numberanimation { property: "angle"; from: 1; to: 360; duration: 500 } numberanimation { property: "spread"; from: 1; to: 100; duration: 500 } } } exit: transition { parallelanimation { numberanimation { property: "angle"; from: 360; to: 1; duration: 500 } numberanimation { property: "spread"; from: 100; to: 1; duration: 500 } } } background: item { } contentitem: pathview { model: control.popup.visible ? control.delegatemodel : null //currentindex: control.highlightedindex //highlightrangemode: pathview.nohighlightrange interactive: false path: path { //一个圆环路径 pathanglearc { centerx: 100; centery: 100 radiusx: pop.spread; radiusy: pop.spread movetostart: true startangle: 0 sweepangle: pop.angle } } } } }
import qtquick 2.12 import qtquick.controls 2.12 //环形菜单 //龚建波 2022-03-13 //note:弹框为pop会被限制在window内 menu { id: control implicitwidth: 250 implicitheight: 250 margins: 0 padding: 0 //pathview环形的角度范围和延申半径 property int angle: 1 property int spread: 1 //pop弹出和隐藏时的过渡动画 enter: transition { parallelanimation { numberanimation { property: "angle"; from: 1; to: 360; duration: 500 } numberanimation { property: "spread"; from: 1; to: 100; duration: 500 } } } exit: transition { parallelanimation { numberanimation { property: "angle"; from: 360; to: 1; duration: 500 } numberanimation { property: "spread"; from: 100; to: 1; duration: 500 } } } delegate: menuitem { id: item width: 30 height: width padding: 0 spacing: 0 indicator: null arrow: null background: rectangle { radius: width / 2 color: "red" border.color: "black" } contentitem: text { text: item.text padding: 0 verticalalignment: text.alignvcenter horizontalalignment: text.alignhcenter } } contentitem: pathview { implicitwidth: 250 implicitheight: 250 model: control.contentmodel //把pathview放menu,会有一个高亮item被放到contentmodel,减去 pathitemcount: control.count > 0 ? control.count - 1 : 0 //currentindex: control.currentindex //highlightrangemode: pathview.nohighlightrange interactive: false path: path { //一个圆环路径 pathanglearc { centerx: 125; centery: 125 radiusx: control.spread; radiusy: control.spread movetostart: true startangle: 0 sweepangle: control.angle } } } background: item { } }
到此这篇关于qt5中qml自定义环形菜单/环形选择框的实现的文章就介绍到这了,更多相关qt5 qml环形菜单内容请搜索<计算机技术网(www.ctvol.com)!!>以前的文章或继续浏览下面的相关文章希望大家以后多多支持<计算机技术网(www.ctvol.com)!!>!
需要了解更多c/c++开发分享Qt5中QML自定义环形菜单/环形选择框的实现,都可以关注C/C++技术分享栏目—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/1082350.html