QML QtQuick.Controls 2 SpinBox数字框样式自定义

版本: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"
            }
        }
发布了95 篇原创文章 · 获赞 26 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/gongjianbo1992/article/details/101911764