Перелистываемая кнопка в QML

я хочу создать компонент, который может перемещать прямоугольник слева направо для имитации включения или выключения, как кнопка iOS слева направо для выключения телефона (https://thewikihow.com/video_qEJ5PerUqFw?t=42 секунда 40 так). Знаешь, как я могу это сделать?

С наилучшими пожеланиями

Я пытаюсь использовать компоненты Slider и SwipeDelegate.

5 дизайнов темных кнопок с использованием HTML и CSS
5 дизайнов темных кнопок с использованием HTML и CSS
Здесь представлены пять дизайнов темных кнопок с кодом с использованием HTML и CSS:
1
0
58
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

В 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"); }
    }
}

Вау, спасибо большое. Я попробовал использовать SwipeDelegate (doc.qt.io/qt-6/qml-qtquick-controls-swipedelegate.html#deta‌​ils), но мне показалось, что его сложно расширить. У меня нет навыков UI/UX. Ваше решение простое и красивое. Еще раз спасибо.

Bondrusiek 18.07.2024 15:43

Я был рад помочь. Не забудьте адаптировать его, этот код представляет собой просто пример жестко закодированных значений, фиксированных макетов и т. д., вы знаете...

folibis 18.07.2024 15:50

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>

Вы можете Попробовать онлайн

Использованная литература:

Спасибо за ответ. Ваш компонент красивый и практичный.

Bondrusiek 19.07.2024 14:31

Другие вопросы по теме