版本:Qt5.12.5 ,参考Qt源码及文档示例
代码链接:https://github.com/gongjianbo/QmlComponentStyle.git
在Qt5.12的文档中你可以搜索到三个MenuBar组件,这里我修改的是Control2中的菜单栏样式,对比如下:



因为菜单栏及菜单项是多个组件组合而成的,都需要进行了自定义来统一风格:

样式修改也没什么好讲的,就那几个固定的设置,要做的就是改改属性参数来实现界面效果。QML这个MenuBar有个好处就是能随便放在哪个位置,Menu也可以单独作为弹出式的菜单。直接放代码:
//basicmenu.qml
//basicmenu.qml import QtQuick 2.12 import QtQuick.Controls 2.12 import QtQuick.Controls.impl 2.12 import QtQuick.Templates 2.12 as T import QtQuick.Window 2.12 T.Menu { id: control property color borderColor: "black" property color backgroundColor: "white" implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, contentWidth + leftPadding + rightPadding) implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, contentHeight + topPadding + bottomPadding) margins: 0 overlap: 1 font{ family: "SimSun" pixelSize: 14 } delegate: BasicMenuItem { } contentItem: ListView { implicitHeight: contentHeight model: control.contentModel interactive: Window.window ? contentHeight > Window.window.height : false clip: true currentIndex: control.currentIndex ScrollIndicator.vertical: ScrollIndicator {} } background: Rectangle { implicitWidth: 122 implicitHeight: 32 color: control.backgroundColor border.width: 1 border.color: control.borderColor } T.Overlay.modal: Rectangle { color: Color.transparent(control.palette.shadow, 0.5) } T.Overlay.modeless: Rectangle { color: Color.transparent(control.palette.shadow, 0.12) } }
//basicmenubar.qml
//basicmenubar.qml import QtQuick 2.12 import QtQuick.Templates 2.12 as T import QtQuick.Controls 2.12 import QtQuick.Controls.impl 2.12 T.MenuBar { id: control property color backgroundColor: "white" property color borderColor: "black" implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, contentWidth + leftPadding + rightPadding) implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, contentHeight + topPadding + bottomPadding) font{ family: "SimSun" pixelSize: 16 } delegate: BasicMenuBarItem { } contentItem: Row { spacing: control.spacing Repeater { model: control.contentModel } } //背景在MenuBarItem之下,我把MenuBarItem的background高度去了1px background: Rectangle { implicitHeight: 30 color: control.backgroundColor Rectangle { color: control.borderColor width: parent.width height: 1 anchors.bottom: parent.bottom } } }
//basicmenubaritem.qml
//basicmenubaritem.qml import QtQuick 2.12 import QtQuick.Templates 2.12 as T import QtQuick.Controls 2.12 import QtQuick.Controls.impl 2.12 T.MenuBarItem { id: control property color textColor: control.highlighted ? "cyan" : "white" property color backgroundColor: control.down || control.highlighted ? "black" : "gray" implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, implicitContentWidth + leftPadding + rightPadding) implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, implicitContentHeight + topPadding + bottomPadding, implicitIndicatorHeight + topPadding + bottomPadding) //spacing: 6 padding: 0 leftPadding: 12 rightPadding: 12 //icon.width: 24 //icon.height: 24 //icon.color: control.palette.buttonText contentItem: Text { text: control.text font: control.font //opacity: enabled ? 1.0 : 0.3 color: control.textColor horizontalAlignment: Text.AlignLeft verticalAlignment: Text.AlignVCenter renderType: Text.NativeRendering elide: Text.ElideRight } background: Rectangle { implicitHeight: 30 height: control.height-1 color: control.backgroundColor } }
//basicmenuitem.qml
//basicmenuitem.qml import QtQuick 2.12 import QtQuick.Controls 2.12 import QtQuick.Controls.impl 2.12 import QtQuick.Templates 2.12 as T import QtQuick.Shapes 1.12 T.MenuItem { id: control property color textColor: control.highlighted ? "cyan" : "black" property color buttonColor: control.down ? "black": control.highlighted ? "gray": "transparent" property color indicatorColor: "black" property color arrowColor: "black" implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, implicitContentWidth + leftPadding + rightPadding) implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, implicitContentHeight + topPadding + bottomPadding, implicitIndicatorHeight + topPadding + bottomPadding) padding: 0 spacing: 6 contentItem: Text { readonly property real arrowPadding: control.subMenu && control.arrow ? control.arrow.width + control.spacing : 0 readonly property real indicatorPadding: control.checkable && control.indicator ? control.indicator.width + control.spacing : 0 readonly property real left_pd: !control.mirrored ? indicatorPadding : arrowPadding //没有边距就贴在边上了 leftPadding: left_pd<=0?6:left_pd rightPadding: control.mirrored ? indicatorPadding : arrowPadding horizontalAlignment: Text.AlignLeft verticalAlignment: Text.AlignVCenter renderType: Text.NativeRendering text: control.text font: control.font color: control.textColor } indicator: Item { x: control.mirrored ? control.width - width - control.rightPadding : control.leftPadding //y: control.topPadding + (control.availableHeight - height) / 2 implicitWidth: 30 implicitHeight: 30 Rectangle { width: parent.width-8 height: width anchors.centerIn: parent visible: control.checkable border.width: 1 border.color: control.indicatorColor Rectangle { width: parent.width-8 height: width anchors.centerIn: parent visible: control.checked color: control.indicatorColor } } } arrow: Shape { id: item_arrow x: control.mirrored ? control.leftPadding : control.width - width - control.rightPadding //y: control.topPadding + (control.availableHeight - height) / 2 visible: control.subMenu implicitWidth: 30 implicitHeight: 30 ShapePath { strokeWidth: 0 strokeColor: control.arrowColor fillRule: ShapePath.WindingFill fillColor: control.arrowColor startX: item_arrow.width/4 startY: item_arrow.height*3/4 PathLine { x:item_arrow.width/4; y:item_arrow.height/4 } PathLine { x:item_arrow.width/2; y:item_arrow.height/2 } PathLine { x:item_arrow.width/4; y:item_arrow.height*3/4 } } } background: Rectangle { implicitWidth: 120 implicitHeight: 30 x: 1 y: 1 width: control.width - 2 height: control.height - 2 color: control.buttonColor } }
//basicmenuseparator.qml
//basicmenuseparator.qml import QtQuick 2.12 import QtQuick.Controls 2.12 import QtQuick.Controls.impl 2.12 import QtQuick.Templates 2.12 as T T.MenuSeparator { id: control property color contentColor: "black" property color backgroundColor: "transparent" implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, implicitContentWidth + leftPadding + rightPadding) implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, implicitContentHeight + topPadding + bottomPadding) padding: 0 topPadding: 4 bottomPadding: 4 contentItem: Rectangle { implicitWidth: 120 implicitHeight: 1 color: contentColor } background: Rectangle{ color: backgroundColor } }
//main.qml 使用
MenuBar{ width: 600 Menu{ title: "MenuA" Action{ text: "A"; checkable: true; checked: true } Action{ text: "B"; checkable: true; } MenuSeparator{} Menu{ title: "C" Action{ text: "A" } Action{ text: "B" } } } Menu{ title: "Menu Test" Action{ text: "A" } Action{ text: "B" } } } BasicMenuBar{ width: 600 height: 30 BasicMenu{ title: "MenuA" Action{ text: "A"; checkable: true; checked: true } Action{ text: "B"; checkable: true; } BasicMenuSeparator{ } BasicMenu{ title: "C" Action{ text: "A" } Action{ text: "B" } } } BasicMenu{ title: "Menu Test" Action{ text: "A" } Action{ text: "B" } } }
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/218380.html原文链接:https://javaforall.net
