兼容Qt4/Qt5版本Qml控件Slider

通过滑动滑块选择一个值

方法

描述

通过滑动滑块选择一个值

1
2
3
Slider {
value: 0.5
}

示例

Slider

属性文档

  • background: Item
    该属性保留着滑动选择控件的背景元素.

  • from : real
    该属性保留着范围的起始值.默认值为0.0.
    更多相关请查看tovalue.

  • handle : Item
    该属性保留着滑动滑块的元素.

  • orientation : enumeration
    该属性保留着滑动条方向.
    可能的值:
描述
Qt.Horizontal 水平方向(默认)
Qt.Vertical 垂直方向

  • [只读属性] position: real
    该属性保留着滑块的逻辑位置.逻辑位置为百分比值(0.0-1.0)拖动滑块该值会不断更新.

  • pressed : bool
    该属性保留着是否按下滑块.

  • stepSize : real
    该属性保留着滑块每次的步长.
    更多相关请查看increase()decrease()

  • to : real
    该属性保留着范围的结束值.默认值为1.0.
    更多相关请查看tovalue.

  • 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.

关于更新

  • 文章首发于微信公众号你才小学生(nicaixiaoxuesheng)
  • 后续更新于Qtbig哥(qtbig.com)

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
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)
}
}
}