Time Picker example shows how to implement a time picker widget for the application. The widget is created as a modal dialog with two vertical ListView elements: one for choosing hours and another one for choosing minutes. The default values follow the current time. User can quickly flick to the wanted time or select visible hour and minute items by tapping.
Show code ยป
timepicker.qml:
import QtQuick 1.0 Rectangle { color: Qt.rgba(1.0, 0.9, 0.6) width: 800; height: 500 TimePickerDialog { id: timePickerDialog anchors.centerIn: parent } Button { width: 130 text: "Open" anchors.centerIn: parent onClicked: timePickerDialog.show() } }
TimePickerDialog.qml:
import QtQuick 1.0 Rectangle { id: timePicker property int hours property int minutes property string text: qsTr("Set time to") z: 2 radius: 4 scale: 0.0 color: Qt.rgba(0.1, 0.1, 0.1, 0.9) width: 320; height: contentColumn.height + 4 border { width: 2; color: Qt.rgba(1.0, 1.0, 1.0, 0.2) } signal finished signal canceled onFinished: timePicker.state = "" onCanceled: timePicker.state = "" function show() { state = "visible" } function formatTime() { var time = new Date() time.setHours(hours) time.setMinutes(5*Math.round(minutes/5)) return Qt.formatDateTime(time, "hh:mm") } Column { id: contentColumn x: 2; width: parent.width - 4 Text { color: "white" height: 80 font.pixelSize: 32 text: timePicker.text + " " + timePicker.formatTime() elide: Text.ElideRight verticalAlignment: Text.AlignVCenter anchors.horizontalCenter: parent.horizontalCenter } Rectangle { color: Qt.rgba(0.9, 0.9, 0.9) x: 10; y: 6; height: 300; width: parent.width - 20 Row { clip: true spacing: 1 anchors.fill: parent ListView { id: hourList width: parent.width/2; height: 300 model: ListModel { id: hourModel Component.onCompleted: { for (var index = 0; index < 24; index++) append({"hours": index}) hourList.currentIndex = Math.ceil(new Date().getHours()) } } delegate: TimePickerItem { number: hours onIsCurrentItemChanged: { if (isCurrentItem) timePicker.hours = hours } } snapMode: ListView.SnapToItem flickDeceleration: 1000 preferredHighlightBegin: 120; preferredHighlightEnd: 120 highlightRangeMode: ListView.StrictlyEnforceRange highlight: Item {} } ListView { id: minuteList width: parent.width/2; height: 300 model: ListModel { id: minuteModel Component.onCompleted: { for (var index = 0; index < 12; index++) append({"minutes": 5*index}) minuteList.currentIndex = Math.ceil(new Date().getMinutes()/5) } } delegate: TimePickerItem { number: minutes onIsCurrentItemChanged: { if (isCurrentItem) timePicker.minutes = minutes } } snapMode: ListView.SnapToItem flickDeceleration: 1000 preferredHighlightBegin: 120; preferredHighlightEnd: 120 highlightRangeMode: ListView.StrictlyEnforceRange highlight: Item {} } } Rectangle { // highlight height: 60; width: parent.width color: Qt.rgba(0.2, 0.5, 0.8, 0.4) anchors.centerIn: parent } Rectangle { height: 55; width: parent.width gradient: Gradient { GradientStop { position: 1.0; color: Qt.rgba(0,0,0,0) } GradientStop { position: 0.0; color: Qt.rgba(0,0,0,0.6) } } anchors.top: parent.top } Rectangle { height: 55; width: parent.width gradient: Gradient { GradientStop { position: 0.0; color: Qt.rgba(0,0,0,0) } GradientStop { position: 1.0; color: Qt.rgba(0,0,0,0.6) } } anchors.bottom: parent.bottom } } Item { width: 1; height: 10 } Row { height: 70; width: parent.width Button { text: qsTr("Ok") width: parent.width/2 - 2 onClicked: timePicker.finished() } Rectangle { width: 2; height: 70 color: Qt.rgba(1.0, 1.0, 1.0, 0.2) } Button { text: qsTr("Cancel") width: parent.width/2-2 onClicked: timePicker.canceled() } } } Rectangle { id: fadeBackground z: 1 opacity: 0.0 color: Qt.rgba(0.0, 0.0, fadeBackgroundMouse.pressed ? 0.5 : 0.45) parent: timePicker.parent anchors.fill: parent MouseArea { id: fadeBackgroundMouse enabled: false anchors.fill: parent onClicked: timePicker.canceled() } } states: State { name: "visible" PropertyChanges { target: timePicker; scale: 1.0 } PropertyChanges { target: fadeBackgroundMouse; enabled: true } PropertyChanges { target: fadeBackground; opacity: 0.45 } } transitions: Transition { NumberAnimation { properties: "opacity, scale" duration: 500; easing.type: Easing.InOutQuad } } }
TimePickerItem.qml:
import QtQuick 1.0 Rectangle { id: timePickerItem property int number property bool pressed: itemMouse.pressed || highlightTimer.running property bool isCurrentItem: ListView.isCurrentItem color: index % 2 ? "white" : "lightgray" height: 60; width: parent.width Rectangle { color: "black" opacity: parent.pressed ? 0.3 : 0.0 anchors { fill: parent; margins: -1 } Behavior on opacity { NumberAnimation { duration: 200; easing.type: Easing.InOutQuad } } } MouseArea { id: itemMouse anchors.fill: parent enabled: !ListView.isCurrentItem onClicked: ListView.view.currentIndex = index } Text { text: number >= 0 ? number : "" font.pixelSize: 26 anchors.centerIn: parent } Timer { id: highlightTimer interval: 200 running: parent.pressed } }
Button.qml:
import QtQuick 1.0 Rectangle { property string text radius: 4.0 color: "black" width: 107; height: 70 scale: buttonMouse.pressed ? 0.95 : 1.0 Behavior on scale { NumberAnimation { duration: 100; easing.type: Easing.InOutQuad } } signal clicked Text { color: "white" text: parent.text font.pixelSize: 28 elide: Text.ElideRight smooth: buttonMouse.pressed anchors.centerIn: parent } MouseArea { id: buttonMouse anchors.fill: parent onClicked: parent.clicked() } }