я хочу создать компонент, который может перемещать прямоугольник слева направо для имитации включения или выключения, как кнопка iOS слева направо для выключения телефона (https://thewikihow.com/video_qEJ5PerUqFw?t=42 секунда 40 так). Знаешь, как я могу это сделать?
С наилучшими пожеланиями
Я пытаюсь использовать компоненты Slider и SwipeDelegate.
В QML можно создавать все, что угодно, но следует придерживаться стандартных элементов управления, поскольку они понятны и знакомы пользователям. Если вы все еще хотите создать какой-то собственный элемент управления, вы можете создать что-то вроде этого:
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.info(isOn ? "ON" : "OFF"); }
}
}
Я был рад помочь. Не забудьте адаптировать его, этот код представляет собой просто пример жестко закодированных значений, фиксированных макетов и т. д., вы знаете...
Slider
довольно близко.
Slider {
property bool checked: !pressed && value === to
stepSize: to
snapMode: Slider.SnapOnRelease
}
Вы можете настроить стиль Slider
, чтобы он был ближе к тому, что вы хотите:
// 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>
Вы можете Попробовать онлайн
Использованная литература:
Спасибо за ответ. Ваш компонент красивый и практичный.
Вау, спасибо большое. Я попробовал использовать SwipeDelegate (doc.qt.io/qt-6/qml-qtquick-controls-swipedelegate.html#details), но мне показалось, что его сложно расширить. У меня нет навыков UI/UX. Ваше решение простое и красивое. Еще раз спасибо.