Reputation: 3
i wanna create a component which can slide a rectangle from left to right to simulate ON or OFF like a iOS left-to-right button to shutdown phone (https://youtu.be/qEJ5PerUqFw?t=42 second 40 like this). Do you know how can I do this ?
Best regard
I try to use Slider and SwipeDelegate components.
Upvotes: -2
Views: 118
Reputation: 26214
Slider
is pretty close.
Slider {
property bool checked: !pressed && value === to
stepSize: to
snapMode: Slider.SnapOnRelease
}
You can customize the Slider
style to get closer to what you want:
// SwipeButton.qml
import QtQuick
import QtQuick.Controls
Slider {
id: control
property bool checked: !pressed && value === to
property string fromText: qsTr("Swipe me")
property color fromColor: "white"
property color fromTextColor: "green"
property url fromHandle: "FromHandle.svg"
property string toText: qsTr("Swiped!")
property color toColor: "green"
property color toTextColor: "white"
property url toHandle: "ToHandle.svg"
stepSize: to
snapMode: Slider.SnapOnRelease
background: Rectangle {
implicitWidth: 300
implicitHeight: 50
border.color: c(fromTextColor, toTextColor, control.visualPosition)
color: c(fromColor, toColor, control.visualPosition)
radius: 4
Text {
anchors.centerIn: parent
text: fromText
opacity: 1-control.visualPosition
color: fromTextColor
}
Text {
anchors.centerIn: parent
text: toText
opacity: control.visualPosition
color: toTextColor
}
}
handle: Item {
x: control.leftPadding + control.visualPosition * (control.availableWidth - width)
y: control.topPadding + control.availableHeight / 2 - height / 2
width: 42
height: 42
Image {
anchors.fill: parent
source: fromHandle
sourceSize: Qt.size(width, height)
opacity: 1-control.visualPosition
cache: false
}
Image {
anchors.fill: parent
source: toHandle
sourceSize: Qt.size(width, height)
opacity: control.visualPosition
cache: false
}
}
function c(c1, c2, t) {
c1 = Qt.color(c1);
c2 = Qt.color(c2);
let r = c1.r * (1-t) + c2.r * t;
let g = c1.g * (1-t) + c2.g * t;
let b = c1.b * (1-t) + c2.b * t;
return Qt.rgba(r,g,b,1);
}
}
// FromHandle.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<rect x="2" y="2" width="28" height="28" rx="4" stroke="white" stroke-width="0.2" fill="green" />
<path stroke="white" stroke-width="1" fill="transparent" d="M 13 8 l 8 8 l -8 8"/>
</svg>
// ToHandle.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<rect x="2" y="2" width="28" height="28" rx="4" stroke="green" stroke-width="0.2" fill="white" />
<path stroke="green" stroke-width="1" fill="transparent" d="M 10 16 l 4 4 l 8 -8"/>
</svg>
You can Try it Online
References:
Upvotes: 0
Reputation: 12874
In QML, you can create whatever you want, but you should stick to standard controls because they are understandable and familiar to users. If you still want to create some kind of custom control, you can create something like this:
import QtQuick
import QtQuick.Controls
Window {
id: window
visible: true
width: 600
height: 400
title: "Slider test"
Rectangle {
id: container
anchors.centerIn: parent
width: 300
height: 50
radius: 25
color: "lightgrey"
border.color: "grey"
signal myEvent(bool isOn)
Rectangle {
id: draggableRect
width: 50
height: 48
radius: 25
color: "orange"
border.color: "grey"
x: 1
y: 1
MouseArea {
id: dragArea
anchors.fill: parent
drag.target: parent
drag.axis: Drag.XAxis
drag.maximumX: 250
drag.minimumX: 0
onReleased: {
if (draggableRect.x < 240)
{
backAnim.running = true;
}
else
{
draggableRect.x = 250;
container.myEvent(true);
}
}
}
PropertyAnimation { id: backAnim; target: draggableRect; property: "x"; to: 1; duration: 300; onFinished: container.myEvent(false); }
}
}
Connections {
target: container
function onMyEvent(isOn) { console.log(isOn ? "ON" : "OFF"); }
}
}
Upvotes: 1