QMLQtQuick.Controls2ComboBox下拉框样式⾃定义(2020-12-27代码已更新,移除Shape图标绘制,改⽤impl中的ColorImage加载按钮图标)
测试版本:Qt5.12及Qt5.15,参考Qt源码及⽂档⽰例
⾃定义样式与默认样式的对⽐:
扁平样式实现代码:
//第⼀版 BasicComboBox (2019-12 已过期)
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Templates 2.12 as T
import QtQuick.Controls 2.12
import QtQuick.Shapes 1.12
import QtQuick.Controls.impl 2.12
//qtquickcontrols2\src\imports\controls\ComboBox.qml
//from Customizing ComboBox
T.ComboBox {
id:control
//可以像源码⼀样,定义⼀个全局的样式,然后取全局样式中对应的颜⾊
//checked选中状态,down按下状态,hovered悬停状态
property color textColor: "white" //⽂字颜⾊
property color backgroundTheme: "darkCyan"
property color backgroundColor: control.down
Qt.darker(backgroundTheme)
: control.hovered
Qt.lighter(backgroundTheme)
: backgroundTheme
property color itemHighlightColor: Qt.darker(backgroundTheme)
property color itemNormalColor: backgroundTheme
property color indicatorColor: "white" //勾选框颜⾊
property int radius: 0
property int showCount: 5 //最多显⽰的item个数
//property int _globalY: mapToGlobal(control.x,control.y).y
//property int _globalHeight: Screen.desktopAvailableHeight
implicitWidth: 120
implicitHeight: 30
spacing: 5
leftPadding: padding
rightPadding: padding + indicator.width + spacing
font{
family: "SimSun"
pixelSize: 16
}
//各item
delegate: ItemDelegate {
implicitWidth: control.implicitWidth
implicitHeight: control.implicitHeight
width: control.width
contentItem: Text {
contentItem: Text {
text: Role
(Array.del)
Role]
: Role])
: modelData
color: Color
font: control.font
elide: Text.ElideRight
renderType: Text.NativeRendering
verticalAlignment: Text.AlignVCenter
}
hoverEnabled: control.hoverEnabled
background: Rectangle{
//radius: control.radius
color: (control.highlightedIndex === index)
control.itemHighlightColor
: control.itemNormalColor
Rectangle{
height: 1
width: parent.width
anchors.bottom: parent.bottom
color: Qt.lighter(itemNormalColor)
}
}
}
//图标⾃⼰画⽐较⿇烦,还是贴图⽅便
indicator: Shape {
id: box_indicator
x: control.width - width - control.padding
y: pPadding + (control.availableHeight - height) / 2
width: height*2
height: control.height/2
//smooth: true //平滑处理
/
/antialiasing: true //反⾛样抗锯齿
ShapePath {
strokeWidth: 1
strokeColor: indicatorColor
//fillRule: ShapePath.WindingFill
fillColor: "transparent"
//fillColor: control.down ? itemHighlightColor : itemNormalColor startX: 0; startY: 4
PathLine { x:0; y:0 }
PathLine { x:box_indicator.width-8+1; y:0 } //+1补齐
PathLine { x:box_indicator.width-8+1; y:4 }
PathLine { x:0; y:4 }
PathLine { x:(box_indicator.width-8)/2; y:box_indicator.height } PathLine { x:box_indicator.width-8; y:4 }
}
}
//box显⽰item
contentItem: T.TextField{
leftPadding: 10
rightPadding: 6
text: control.editable ? control.editText : control.displayText
font: control.font
color: Color
verticalAlignment: Text.AlignVCenter
//默认⿏标选取⽂本设置为false
selectByMouse: true
//选中⽂本的颜⾊
selectedTextColor: "white"
//选中⽂本背景⾊
selectionColor: "black"
selectionColor: "black"
clip: true
renderType: Text.NativeRendering
enabled: control.editable
autoScroll: control.editable
readOnly: control.down
inputMethodHints: control.inputMethodHints
validator: control.validator
background: Rectangle {
visible: abled && control.editable
border.width: parent && parent.activeFocus ? 1 : 0
color: "transparent"
}
}
//box框背景
background: Rectangle {
implicitWidth: control.implicitWidth
implicitHeight: control.implicitHeight
radius: control.radius
color: control.backgroundColor
}
//弹出框
popup: T.Popup {
//默认向下弹出,如果距离不够,y会⾃动调整()
y: control.height
width: control.width
/
/根据showCount来设置最多显⽰item个数
implicitHeight: (unt<showCount
contentItem.implicitHeight
:showCount*control.implicitHeight)+2
padding: 1
contentItem: ListView {
clip: true
implicitHeight: contentHeight
model: control.popup.visible ? control.delegateModel : null
currentIndex: control.highlightedIndex
snapMode: ListView.SnapToItem //按⾏滚动
/
/ScrollBar.horizontal: ScrollBar { visible: false }
ScrollBar.vertical: ScrollBar { //定制滚动条
id: box_bar
implicitWidth: 10
visible: (unt>showCount)
//background: Rectangle{} //这是整体的背景
contentItem: Rectangle{
implicitWidth:10
radius: width/2
color: box_bar.pressed
:
Qt.rgba(0.6,0.6,0.6,0.5)
}
}
}
//弹出框背景(只有border显⽰出来了,其余部分被delegate背景遮挡) background: Rectangle {
border.width: 1
//color: Qt.lighter(themeColor)
radius: control.radius
}
}
}
}
//第⼆版 BasicComboBox2 (2020-12 使⽤中)
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Templates 2.12 as T
import QtQuick.Controls 2.12
import QtQuick.Controls.impl 2.12
//2019-12-6
//对上⼀版本下拉框的改进
//2019-12-10
/
/改进:判断control.delegateModel,增加spacerponent
//2020-12-26
//移除text和indicator间的竖线spacer
//
//qtquickcontrols2\src\imports\controls\ComboBox.qml
//from Customizing ComboBox
T.ComboBox {
id:control
//checked选中状态,down按下状态,hovered悬停状态
property color backgroundTheme: "darkCyan"
//下拉框背景⾊
property color backgroundColor: control.down
Qt.darker(backgroundTheme)
: control.hovered
Qt.lighter(backgroundTheme)
: backgroundTheme
//边框颜⾊
property color borderColor: Qt.darker(backgroundTheme)
//item⾼亮颜⾊
property color itemHighlightColor: Qt.darker(backgroundTheme)
//item普通颜⾊
property color itemNormalColor: backgroundTheme
/
/每个item的⾼度
property int itemHeight: height
//每个item⽂本的左右padding
property int itemPadding: 10
//下拉按钮颜⾊
//property color indicatorColor: "white"
//下拉按钮左右距离
property int indicatorPadding: 3
//下拉按钮图标
property url indicatorSource: "qrc://imports/QtQuick/Controls.2/images/double-arrow.png" //圆⾓
property int radius: 0
//最多显⽰的item个数
property int showCount: 5
//⽂字颜⾊
property color textColor: "white"
//model数据左侧附加的⽂字
property string textLeft: ""
//model数据右侧附加的⽂字
property string textRight: ""
implicitWidth: 120
implicitHeight: 30
spacing: 0
leftPadding: padding
rightPadding: padding + indicator.width + spacing
font{
family: "SimSun"
pixelSize: 16
}
//各item
delegate: ItemDelegate {
id: box_item
height: control.itemHeight
//Popup如果有padding,这⾥要减掉2*pop.padding
width: control.width
padding: 0
contentItem: Text {
text: Left+
(Role
(Array.del)
Role]
: Role])
: modelData)+
color: Color
leftPadding: control.itemPadding
rightPadding: control.itemPadding
font: control.font
elide: Text.ElideRight
renderType: Text.NativeRendering
verticalAlignment: Text.AlignVCenter
}
hoverEnabled: control.hoverEnabled
background: Rectangle{
radius: control.radius
color: (control.highlightedIndex === index)
control.itemHighlightColor
: control.itemNormalColor
//item底部的线
Rectangle{
height: 1
width: parent.width-2*control.radius
anchors.bottom: parent.bottom
borderboxanchors.horizontalCenter: parent.horizontalCenter
color: Qt.lighter(control.itemNormalColor)
}
}
}
//之前⽤的Shape,现在替换为Image
//图标⾃⼰画⽐较⿇烦,还是贴图⽅便,使⽤的时候换成⾃⼰图 indicator: Item{
id: box_indicator
x: control.width - width
y: pPadding + (control.availableHeight - height) / 2 width: box_indicator_img.width+control.indicatorPadding*2 height: control.height
//按钮图标
Image {
id: box_indicator_img
//width: height
//height: control.height
//fillMode: Image.PreserveAspectFit
source: control.indicatorSource
}
}
//box显⽰item
contentItem: T.TextField{
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论