版本:Qt5.12.5 ,参考Qt源码及文档示例
代码链接:https://github.com/gongjianbo/QmlComponentStyle.git
自定义样式与默认样式的对比:
扁平样式实现代码:
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Controls.impl 2.12
import QtQuick.Templates 2.12 as T
//qtquickcontrols2\src\imports\controls\SpinBox.qml
//from Customizing SpinBox
T.SpinBox {
id: control
property bool borderVisible: true //显示边框
property color borderColor: "darkCyan" //边框颜色
property color textColor: "black" //文本颜色
property color bgNormalColor: "white" //文本背景色
property color bgFocusColor: bgNormalColor //文本背景焦点色
property color indicatorNormalColor: "black" //按钮图标颜色
property color indicatorDisableColor: "gray"
property color btnNormalColor: "white" //按钮背景颜色
property color btnHoverColor: Qt.lighter(btnNormalColor)
property color btnPressColor: Qt.darker(btnNormalColor)
implicitWidth: 120
implicitHeight: 30
/*implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
contentItem.implicitWidth + 2 * padding +
up.implicitIndicatorWidth +
down.implicitIndicatorWidth)
implicitHeight: Math.max(implicitContentHeight + topPadding + bottomPadding,
implicitBackgroundHeight,
up.implicitIndicatorHeight,
down.implicitIndicatorHeight)*/
padding: 0
leftPadding: padding + (down.indicator ? down.indicator.width : 0)
rightPadding: padding + (up.indicator ? up.indicator.width : 0)
font{
family: "SimSun"
pixelSize: 16
}
validator: IntValidator {
locale: control.locale.name
bottom: Math.min(control.from, control.to)
top: Math.max(control.from, control.to)
}
contentItem: Rectangle{
z: 2
color: control.activeFocus
?bgFocusColor
:bgNormalColor;
TextInput {
anchors.fill: parent
text: control.displayText
horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignVCenter
readOnly: !control.editable
validator: control.validator
inputMethodHints: control.inputMethodHints
color: control.textColor
selectByMouse: true
selectedTextColor: "white"
selectionColor: "black"
font: control.font
renderType: Text.NativeRendering
}
Rectangle{
width: parent.width
height: 1
color: borderVisible?borderColor:"transparent"
}
Rectangle{
width: parent.width
height: 1
anchors.bottom: parent.bottom
color: borderVisible?borderColor:"transparent"
}
}
up.indicator: Rectangle {
x: parent.width - width
height: parent.height
implicitWidth: 30
implicitHeight: 30
color: up.pressed
?btnPressColor
:up.hovered
?btnHoverColor
:btnNormalColor
border.width: borderVisible?1:0
border.color: borderColor
Rectangle {
x: (parent.width - width) / 2
y: (parent.height - height) / 2
width: parent.width / 3
height: 2
color: enabled ? indicatorNormalColor : indicatorDisableColor
}
Rectangle {
x: (parent.width - width) / 2
y: (parent.height - height) / 2
width: 2
height: parent.width / 3
color: enabled ? indicatorNormalColor : indicatorDisableColor
}
}
down.indicator: Rectangle {
x: 0
height: parent.height
implicitWidth: 30
implicitHeight: 30
color: down.pressed
?btnPressColor
:down.hovered
?btnHoverColor
:btnNormalColor
border.width: borderVisible?1:0
border.color: borderColor
Rectangle {
x: (parent.width - width) / 2
y: (parent.height - height) / 2
width: parent.width / 3
height: 2
color: enabled ? indicatorNormalColor : indicatorDisableColor
}
}
//不需要background
background: Item{
implicitWidth: 120
implicitHeight: 30
}
}
//main.qml
Row{
id:spinbox_row
spacing: 10
//参考文档示例里代码
SpinBox{
width: 120
height: 30
//默认范围[0,99],步进1
from: -100
to: 100
value: -100
stepSize: 2
}
SpinBox {
id: spinbox2
width: 150
height: 30
from: 0
to: items.length - 1
value: 1 // "Medium"
property var items: ["Small", "Medium", "Large"]
validator: RegExpValidator {
//js的正则对象
//参数一为正则表达式
//参数二为可选字符,包含属性 "g"、"i" 和 "m",
// 分别用于指定全局匹配、区分大小写的匹配和多行匹配
regExp: new RegExp("(Small|Medium|Large)", "i")
}
textFromValue: function(value) {
return items[value];
}
valueFromText: function(text) {
for (var i = 0; i < items.length; ++i) {
if (items[i].toLowerCase().indexOf(text.toLowerCase()) === 0)
return i
}
return sb.value
}
}
SpinBox{
id: spinbox3
width: 150
height: 30
from: 0
to: 100*100
value: 1111
stepSize: 1
editable: true
//wrap为true则上下按钮设置是循环设置范围内值的
wrap: true
property int decimals: 2
validator: DoubleValidator {
decimals: spinbox3.decimals
bottom: Math.min(spinbox3.from, spinbox3.to)
top: Math.max(spinbox3.from, spinbox3.to)
}
//loale为格式化数据和数字,见control
//如果想使用js的函数作为回调函数,可以看下这部分的源码
textFromValue: function(value, locale) {
return Number(value / 100).toLocaleString(locale, 'f', spinbox3.decimals)
}
valueFromText: function(text, locale) {
return Number.fromLocaleString(locale, text) * 100
}
}
BasicSpinBox{
from: 0
to: 100
value: 10
stepSize: 1
editable: true
}
BasicSpinBox{
from: 0
to: 100
value: 10
stepSize: 1
//editable: true
borderVisible: false
//borderColor: "darkCyan"
textColor: "white"
btnNormalColor: "darkCyan"
bgNormalColor: "skyblue"
bgFocusColor: "blue"
indicatorNormalColor: "white"
indicatorDisableColor: "gray"
}
}