兼容Qt4/Qt5版本Qml控件Slider

小编:啊南 428阅读 2021.01.18

通过滑动滑块选择一个值

  • 导入方法: 文件导入
  • 兼容性:QtQuick1.x与QtQuick2.x
  • 继承: Item
属性
  • background: Item
  • from: real
  • handle: Item
  • orientation: enumeration
  • position: real
  • pressed: bool
  • stepSize: real
  • to: real
  • value: real
方法
  • function decrease()
  • function increase()
描述

通过滑动滑块选择一个值

Slider {
    value: 0.5
}
示例属性文档
  • background:Item该属性保留着滑动选择控件的背景元素.
  • from:real该属性保留着范围的起始值.默认值为0.0. 更多相关请查看to和value.
  • handle:Item该属性保留着滑动滑块的元素.
  • orientation:enumeration该属性保留着滑动条方向. 可能的值:

描述

Qt.Horizontal

水平方向(默认)

Qt.Vertical

垂直方向

  • [只读属性]position:real该属性保留着滑块的逻辑位置.逻辑位置为百分比值(0.0-1.0)拖动滑块该值会不断更新.
  • pressed:bool该属性保留着是否按下滑块.
  • stepSize:real该属性保留着滑块每次的步长. 更多相关请查看increase()和decrease()
  • to:real该属性保留着范围的结束值.默认值为1.0. 更多相关请查看to和value.
  • value:real该属性的值在from到to范围内.默认值为1.0. 该属性与position属性不一样,value为实际值,而position为百分比值;value属性在滑动过程中不会更新值,在释放滑块后才会更新. 更多相关请查看position.
方法文档
  • function decrease() value属性值会按stepSize增加,如果stepSize没有定义则使用默认值增加(0.1). 更多相关请查看stepSize.
  • function increase() value属性值会按stepSize减少,如果stepSize没有定义则使用默认值减少(0.1). 更多相关请查看stepSize.

源码
import QtQuick 2.0

Item {
    id: root
    width: _private.defaultWidth
    height: _private.defaultHeight
    rotation: orientation === Qt.Vertical ? 180 : 0

    /* public */
    // This property holds the starting value for the range. The default value is 0.0.
    property real from: 0.0

    // This property holds the end value for the range. The default value is 1.0.
    property real to: 1.0

    // This property holds the value in the range from - to. The default value is 0.0.
    // Unlike the position property, the value is not updated while the handle is dragged. The value is updated after the value has been chosen and the slider has been released.
    property real value: 0.0

    // This property holds the step size. The default value is 0.0.
    property real stepSize: 0

    // This property holds the orientation.
    // note: [Qt.Horizontal(default) | Qt.Vertical]
    property int  orientation: Qt.Horizontal

    // This property holds the logical position of the handle.
    // The position is defined as a percentage of the control's size, scaled to 0.0 - 1.0.
    // Unlike the value property, the position is continuously updated while the handle is dragged.
    // For visualizing a slider, the right-to-left aware visualPosition should be used instead.
    property real position: 0.0 // note: [read-only]

    // This property holds whether the slider is pressed.
    property bool pressed: false

    // This property holds the handle item.
    property Component handle: _private.defaultHandle

    // This property holds the background item.
    property Component background: _private.defaultBackground

    // Decreases the value by stepSize or 0.1 if stepSize is not defined.
    function decrease() {
        var _stepSize = stepSize === 0 ? 0.1 : stepSize
        position -= _stepSize
    }

    // Increases the value by stepSize or 0.1 if stepSize is not defined.
    function increase() {
        var _stepSize = stepSize === 0 ? 0.1 : stepSize
        position += _stepSize
    }

    /* private */
    /* background */
    Loader {
        id: backgroundId
        anchors.centerIn: parent
        sourceComponent: root.background
    }

    /* handle */
    Loader {
        id: handleId
        sourceComponent: root.handle
    }

    MouseArea {
        id: mouseArea
        anchors.fill: parent
        onPressed: root.pressed = true
        onReleased: {
            root.pressed = false
            root.value = root.position*to
        }
        onPositionChanged: {
            root.position = _private.adjustPosition(mouseArea)
        }
        onClicked: {
            root.position = _private.adjustPosition(mouseArea)
        }
    }

    onValueChanged: {
        if (value > to)
            value = to

        if (value < from)
            value = from

        position = value/to
    }

    onPositionChanged: {
        if (position < 0)
            position = 0

        if (position > 1)
            position = 1

        _private.setHandlePosition()
    }

    Component.onCompleted: _private.setHandlePosition()

    QtObject {
        id: _private
        property real availableWidth: 0
        property real pathRadius: orientation === Qt.Vertical ? root.width * 2 / 15 : root.height * 2 / 15
        property real handleRadius: orientation === Qt.Vertical ? root.width * 3 / 5 : root.height * 3 / 5
        property real pathScale: 1
        property real defaultWidth:  orientation === Qt.Horizontal ? 150 : 30
        property real defaultHeight: orientation === Qt.Vertical ? 150 : 30

        property Component defaultHandle: Rectangle {
            width: _private.handleRadius
            height: width
            radius: width / 2
            color: root.pressed ? "#f0f0f0" : "#f6f6f6"
            border.color: "#bdbebf"
        }

        property Component defaultBackground: Rectangle {
            width:  orientation === Qt.Horizontal ? root.width  : _private.pathRadius
            height: orientation === Qt.Vertical   ? root.height : _private.pathRadius
            radius: 2
            color: "#bdbebf"

            /* available rectangle */
            Rectangle {
                width: orientation === Qt.Horizontal ? position*parent.width : parent.width
                height: orientation === Qt.Vertical ? position*parent.height : parent.height
                radius: parent.radius
                color: "#21be2b"
            }
        }

        function adjustPosition(mouseArea) {
            var _backgroundIdValue = 0
            var _mouseValue = 0
            var _rootValue = 0

            if (orientation === Qt.Vertical) {
                _backgroundIdValue = backgroundId.height
                _mouseValue = mouseArea.mouseY
                _rootValue = root.height
            }
            else {
                _backgroundIdValue = backgroundId.width
                _mouseValue = mouseArea.mouseX
                _rootValue = root.width
            }

            var _position = (_mouseValue / _backgroundIdValue)

            if (stepSize === 0)
                return _position

            if (_position > (position + stepSize))
                return position + stepSize

            if (_position < (position - stepSize))
                return position - stepSize

            return position
        }

        function getX(position) {
            if (orientation === Qt.Horizontal) {
                if (((backgroundId.width*position) - handleId.width/2) <= 0) {
                    return 0
                }
                else if (((backgroundId.width*position) + handleId.width/2) >= backgroundId.width) {
                    return backgroundId.width - handleId.width
                }
                else {
                    return ((backgroundId.width*position) - handleId.width/2)
                }
            }
            else {
                return (root.width - handleId.width)/2
            }
        }

        function getY(position) {
            if (orientation === Qt.Vertical) {
                if (((backgroundId.height*position) - handleId.height/2) <= 0) {
                    return 0
                }
                else if (((backgroundId.height*position) + handleId.height/2) >= backgroundId.height) {
                    return backgroundId.height - handleId.height
                }
                else {
                    return ((backgroundId.height*position) - handleId.height/2)
                }
            }
            else {
                return (root.height - handleId.height)/2
            }
        }

        function setHandlePosition() {
            handleId.x = _private.getX(position)
            handleId.y =  _private.getY(position)
        }
    }
}
关联标签: