Getting Started with QML
September 28, 2018 by Nico Vertriest | Comments
This tutorial shows how to develop a simple alarm application as an introduction to QML and Qt Quick Controls. Until 5.11 the documentation did have an example "Getting Started Programming with Qt Quick", but that was not really written for someone who is a complete beginner in QML, nor did it use Qt Quick Controls.
The example is available in 5.12 and can be found here: Getting Started Programming with Qt Quick.
This is a simple app where the main screen is a ListView, and where most fields are filled using the Tumbler QML type. The app stores the alarms in a ListModel. The application is very similar to the alarm application usually found on an Android or IOS phone.
User Interface
The main screen shows the list of saved alarms:
The detail screen becomes visible when you click a particular alarm. It lets you edit or delete existing alarms. You can also select days on which the alarm needs to be repeated.
The dialog screen is used for adding new alarms. It pops up when you click on the "+" RoundButton on the bottom of the main screen:
Entering and Saving Alarms
Most data is entered with the Tumbler QML type. Below you can see part of AlarmDialog.qml, the dialog for entering new alarms.qml.
contentItem: RowLayout {
RowLayout {
id: rowTumbler
Tumbler {
id: hoursTumbler
model: 24
delegate: TumblerDelegate {
text: formatNumber(modelData)
}
}
Tumbler {
id: minutesTumbler
model: 60
delegate: TumblerDelegate {
text: formatNumber(modelData)
}
}
}
RowLayout {
id: datePicker
Layout.leftMargin: 20
property alias dayTumbler: dayTumbler
property alias monthTumbler: monthTumbler
property alias yearTumbler: yearTumbler
readonly property var days: [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
Tumbler {
id: dayTumbler
function updateModel() {
// Populate the model with days of the month. For example: [0, ..., 30]
var previousIndex = dayTumbler.currentIndex
var array = []
var newDays = datePicker.days[monthTumbler.currentIndex]
for (var i = 1; i <= newDays; ++i)
array.push(i)
dayTumbler.model = array
dayTumbler.currentIndex = Math.min(newDays - 1, previousIndex)
}
Component.onCompleted: updateModel()
delegate: TumblerDelegate {
text: formatNumber(modelData)
}
}
Tumbler {
id: monthTumbler
onCurrentIndexChanged: dayTumbler.updateModel()
model: 12
delegate: TumblerDelegate {
text: window.locale.standaloneMonthName(modelData, Locale.ShortFormat)
}
}
Tumbler {
id: yearTumbler
// This array is populated with the next three years. For example: [2018, 2019, 2020]
readonly property var years: (function() {
var currentYear = new Date().getFullYear()
return [0, 1, 2].map(function(value) { return value + currentYear; })
})()
model: years
delegate: TumblerDelegate {
text: formatNumber(modelData)
}
}
}
}
Clicking on "OK" adds the new alarm to the ListModel with id alarmModel.
onAccepted: {
alarmModel.append({
"hour": hoursTumbler.currentIndex,
"minute": minutesTumbler.currentIndex,
"day": dayTumbler.currentIndex + 1,
"month": monthTumbler.currentIndex + 1,
"year": yearTumbler.years[yearTumbler.currentIndex],
"activated": true,
"label": "",
"repeat": false,
"daysToRepeat": [
{ "dayOfWeek": 0, "repeat": false },
{ "dayOfWeek": 1, "repeat": false },
{ "dayOfWeek": 2, "repeat": false },
{ "dayOfWeek": 3, "repeat": false },
{ "dayOfWeek": 4, "repeat": false },
{ "dayOfWeek": 5, "repeat": false },
{ "dayOfWeek": 6, "repeat": false }
],
})
}
Some notes...
The program handles only the user interface and the ListModel that is storing the alarms. There is no code for storing the alarms physically in JSON format or SQLite, nor for the actual triggering of the alarm with sound or a popup window. Maybe that would be a nice challenge for someone starting with QML.
Blog Topics:
Comments
Subscribe to our newsletter
Subscribe Newsletter
Try Qt 6.6 Now!
Download the latest release here: www.qt.io/download.
Qt 6.6. is a feature release with focus on improving UX capabilities including responsive UI technology and the Qt Graph module.
We're Hiring
Check out all our open positions here and follow us on Instagram to see what it's like to be #QtPeople.