Выбор времени в QML

Мне нужно дать пользователю возможность выбрать дату и время в приложении QML. Для выбора даты есть Calendar в элементах управления QtQuick. Я не нашел подобного элемента управления, чтобы позволить пользователю выбрать время суток.

в интернете есть несколько примеров, как грог или харматан. Я предполагаю, однако, что они не интегрируются с собственным внешним видом и чувствуют себя как другие элементы управления QtQuick делать.

есть ли стандартный подход, о котором я не знаю, хорошие альтернативы, с которыми я не сталкивался, или рекомендации о том, что выбрать?

1 ответов


начиная с Qt 5.5 так называемый Qt Quick Enterprise Controls будет доступен также в community edition Qt под названием Qt Quick Extras. Среди других Tumbler кажется возможным решением для ваших требований: вы можете легко настроить два столбца, один для часов и один для минут.

если вы все еще заинтересованы в круговом выборе (или хотите реализовать свой собственный стакан), вы можете взять различные маршруты, такие как создание собственного компонента, наследуемого от QQuickItem или QQuickPaintedItem или использование пользовательского представления с PathView. Последний случай я собираюсь рассмотреть в этом ответе. Примеры создания пользовательских компонентов см. В приведенных ссылках.

со ссылкой на документацию PathView:

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

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

в следующем примере эти элементы используются для определения кругового выбора времени. Каждый путь строится с использованием currentIndexделегата: целое число используется в качестве модели для PathViews -12 для просмотра часов и 6 для просмотра минут, соответственно. Текст делегатов создается путем использования index вложенное свойство и управление им для генерации значений интервалов часов и 10 минут (см. делегаты Text товары). Наконец, текст текущего элемента (т. е. currentItem) привязан к метке времени в центре окна: как currentIndex и currentItem изменить, также обновляется метка.

общий компонент выглядит так:

enter image description here

highlightкомпоненты (синие и зеленые круги) используются для графического представления редактирования времени: когда видимое время может быть отредактировано, т. е. другое Item пути можно выбрать. Переключение между обычным и режимом редактирования происходит щелчок по метке времени в центре.

когда в режиме редактирования пользователь может просто навести различные значения часов / минут, чтобы выбрать их. Если вновь выбранный час/минута нажата редактирование для этого конкретного PathView отключено, и соответствующий круг подсветки исчезает.

этот код-это просто пример игрушки, чтобы дать вам представление о том, что PathView может использоваться для. Можно сделать несколько улучшений, например анимация, лучшее позиционирование номера, подробное представление минут, приятный фон и так далее. Однако они выходят за рамки w.r.т. вопрос так и не был рассмотрен.

import QtQuick 2.4
import QtQuick.Window 2.2
import QtQuick.Controls.Styles 1.3
import QtQuick.Layouts 1.1

Window {
    visible: true
    width: 280; height: 280

    RowLayout {             // centre time label
        anchors.centerIn: parent
        Text {
            id: h
            font.pixelSize: 30
            font.bold: true
            text: outer.currentItem.text
        }
        Text {
            id: div
            font.pixelSize: 30
            font.bold: true
            text: qsTr(":")
        }
        Text {
            id: m
            font.pixelSize: 30
            font.bold: true
            text: inner.currentItem.text
        }

        MouseArea {
            anchors.fill: parent
            onClicked: outer.choiceActive = inner.choiceActive = !outer.choiceActive
        }
    }


    PathView {          // hours path
        id: outer
        property bool pressed: false
        model: 12

        interactive: false
        highlightRangeMode:  PathView.NoHighlightRange
        property bool choiceActive: false

        highlight: Rectangle {
            id: rect
            width: 30 * 1.5
            height: width
            radius: width / 2
            border.color: "darkgray"
            color: "steelblue"
            visible: outer.choiceActive
        }

        delegate: Item {
            id: del
            width: 30
            height: 30
            property bool currentItem: PathView.view.currentIndex == index
            property alias text : textHou.text
            Text {
                id: textHou
                anchors.centerIn: parent
                font.pixelSize: 24
                font.bold: currentItem
                text: index + 1
                color: currentItem ? "black" : "gray"
            }

            MouseArea {
                anchors.fill: parent
                enabled: outer.choiceActive
                onClicked: outer.choiceActive = false
                hoverEnabled: true
                onEntered: outer.currentIndex = index
            }
        }

        path: Path {
            startX: 200; startY: 40
            PathArc {
                x: 80; y: 240
                radiusX: 110; radiusY: 110
                useLargeArc: false
            }
            PathArc {
                x: 200; y: 40
                radiusX: 110; radiusY: 110
                useLargeArc: false
            }
        }
    }

    PathView {          // minutes path
        id: inner
        property bool pressed: false
        model: 6
        interactive: false
        highlightRangeMode:  PathView.NoHighlightRange
        property bool choiceActive: false

        highlight: Rectangle {
            width: 30 * 1.5
            height: width
            radius: width / 2
            border.color: "darkgray"
            color: "lightgreen"
            visible: inner.choiceActive
        }

        delegate: Item {
            width: 30
            height: 30
            property bool currentItem: PathView.view.currentIndex == index
            property alias text : textMin.text
            Text {
                id: textMin
                anchors.centerIn: parent
                font.pixelSize: 24
                font.bold: currentItem
                text: index * 10
                color: currentItem ? "black" : "gray"
            }

            MouseArea {
                anchors.fill: parent
                enabled: inner.choiceActive
                onClicked: inner.choiceActive = false
                hoverEnabled: true
                onEntered: inner.currentIndex = index
            }
        }

        path: Path {
            startX: 140; startY: 60
            PathArc {
                x: 140; y: 220
                radiusX: 40; radiusY: 40
                useLargeArc: false
            }
            PathArc {
                x: 140; y: 60
                radiusX: 40; radiusY: 40
                useLargeArc: false
            }
        }
    }

    // to set current time!
    onVisibleChanged: {
        var d = new Date();
        outer.currentIndex = d.getUTCHours() % 12
        inner.currentIndex = d.getMinutes() / 10
    }
}