继续我们从头开始的 QML 控件系列,这次我们将实现一个 Slider。Slider 具有value、minimum和maximum公共属性。Slider 是用一个覆盖整个控件的MouseArea实现的,并利用拖动来处理用户左右滑动“药丸”(用户移动的部分)。
背景“托盘”(一条水平线,可以点击)被分成左右两部分,以便在启用时不会通过药丸显示设置为假(因为药丸在禁用状态下是部分透明的) . Slider 唯一棘手的部分是计算像素值和像素值的方程。
Slider.qml
import QtQuick 2.0 Item { id: root // public property double maximum: 10 property double value: 0 property double minimum: 0 signal clicked(double value); //onClicked:{root.value = value; print('onClicked', value)} // private width: 500; height: 100 // default size opacity: enabled && !mouseArea.pressed? 1: 0.3 // disabled/pressed state Repeater { // left and right trays (so tray doesn't shine through pill in disabled state) model: 2 delegate: Rectangle { x: !index? 0: pill.x + pill.width - radius width: !index? pill.x + radius: root.width - x; height: 0.1 * root.height radius: 0.5 * height color: 'black' anchors.verticalCenter: parent.verticalCenter } } Rectangle { // pill id: pill x: (value - minimum) / (maximum - minimum) * (root.width - pill.width) // pixels from value width: parent.height; height: width border.width: 0.05 * root.height radius: 0.5 * height } MouseArea { id: mouseArea anchors.fill: parent drag { target: pill axis: Drag.XAxis maximumX: root.width - pill.width minimumX: 0 } onPositionChanged: if(drag.active) setPixels(pill.x + 0.5 * pill.width) // drag pill onClicked: setPixels(mouse.x) // tap tray } function setPixels(pixels) { var value = (maximum - minimum) / (root.width - pill.width) * (pixels - pill.width / 2) + minimum // value from pixels clicked(Math.min(Math.max(minimum, value), maximum)) // emit } }
Test.qml
import QtQuick 2.0 Slider { property double backend: 0 maximum: 10 value: backend minimum: -10 onClicked: backend = value }