查看官方第一个示例(alarm)源代码
https://doc.qt.io/archives/qt-5.14/qtdoc-tutorials-alarms-example.html
源文件
alarms.pro //项目文件
main.cpp //应用程序的主C++代码文件
qml.qrc //资源文件,其中包含源文件的名称(main.cpp和项目文件除外)
//在 main.cpp 文件中生成代码。 此代码块启用高 DPI 缩放并声明应用程序和引擎。 然后引擎加载我们的主 QML 文件。
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
其他源文件
qtquickcontrols2.conf //选择具有深色主题的材质样式
//以下代码段显示了如何在 Material 样式中设置 Dark 主题:
[Controls]
Style=Material
[Material]
Theme=Dark
Accent=Red
main.qml //链接 Alarmdialog.yaml、Alarmmodel.yaml、Alarmdelegate.yaml 和 Tumblerdelegate.yaml 的 YAML 代码
main.qml //链接 Alarmdialog.yaml、Alarmmodel.yaml、
//mainWindow 是一个 ApplicationWindow QML 类型,是这个应用程序的根项。
ApplicationWindow {
id: window
width: 400
height: 500
visible: true
//ListView alarmListView 将来自alarmModel 的数据与alarmDelegate 中定义的布局相结合。
ListView {
id: alarmListView
anchors.fill: parent
model: AlarmModel {}
delegate: AlarmDelegate {}
}
//可以通过单击 RoundButton addAlarmButton 添加新警报。 单击它会打开一个对话框屏幕alarmDialog
RoundButton {
id: addAlarmButton
text: "+"
anchors.bottom: alarmListView.bottom
anchors.bottomMargin: 8
anchors.horizontalCenter: parent.horizontalCenter
onClicked: alarmDialog.open()
}
AlarmDialog {
id: alarmDialog
x: Math.round((parent.width - width) / 2)
y: Math.round((parent.height - height) / 2)
alarmModel: alarmListView.model
}
AlarmDialog.qml //定义用于添加新警报的对话框
//这个对话框屏幕有一个 RowLayout,每个小时和分钟都有一个 Tumbler,另一个 RowLayout 有一个 Tumbler,每个天、月和年。
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)
}
}
}
}
}
//如果在对话框中单击 OK,输入的数据将被添加到 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 }
],
})
}
onRejected: alarmDialog.close()
AlarmDelegate.qml //定义应用程序主屏幕的布局
//主屏幕中的每个警报都是一个 ItemDelegate。 ItemDelegate 根包含主屏幕和详细屏幕上的所有字段。 详细屏幕的字段仅在单击警报后可见,即当 root.checked 为真时。
ItemDelegate {
id: root
width: parent.width
checkable: true
onClicked: ListView.view.currentIndex = index
contentItem: ColumnLayout {
spacing: 0
RowLayout {
ColumnLayout {
id: dateColumn
readonly property date alarmDate: new Date(
model.year, model.month - 1, model.day, model.hour, model.minute)
Label {
id: timeLabel
font.pixelSize: Qt.application.font.pixelSize * 2
text: dateColumn.alarmDate.toLocaleTimeString(window.locale, Locale.ShortFormat)
}
RowLayout {
Label {
id: dateLabel
text: dateColumn.alarmDate.toLocaleDateString(window.locale, Locale.ShortFormat)
}
Label {
id: alarmAbout
text: "⸱ " + model.label
visible: model.label.length > 0 && !root.checked
}
}
}
Item {
Layout.fillWidth: true
}
Switch {
checked: model.activated
Layout.alignment: Qt.AlignTop
onClicked: model.activated = checked
}
}
CheckBox {
id: alarmRepeat
text: qsTr("Repeat")
checked: model.repeat
visible: root.checked
onToggled: model.repeat = checked
}
Flow {
visible: root.checked && model.repeat
Layout.fillWidth: true
Repeater {
id: dayRepeater
model: daysToRepeat
delegate: RoundButton {
text: Qt.locale().dayName(model.dayOfWeek, Locale.NarrowFormat)
flat: true
checked: model.repeat
checkable: true
Material.background: checked ? Material.accent : "transparent"
onToggled: model.repeat = checked
}
}
}
TextField {
id: alarmDescriptionTextField
placeholderText: qsTr("Enter description here")
cursorVisible: true
visible: root.checked
text: model.label
onTextEdited: model.label = text
}
Button {
id: deleteAlarmButton
text: qsTr("Delete")
width: 40
height: 40
visible: root.checked
onClicked: root.ListView.view.model.remove(root.ListView.view.currentIndex, 1)
}
}
}
AlarmModel.qml //定义用于存储警报数据的 ListModel
//此 QML 文件包含 alarmModel 的定义,即管理警报数据的 ListModel
//它创建了五个带有示例警报的 ListElement
import QtQuick 2.11
// Populate the model with some sample data.
ListModel {
id: alarmModel
ListElement {
hour: 6
minute: 0
day: 2
month: 8
year: 2018
activated: true
label: "Wake up"
repeat: true
daysToRepeat: [
ListElement { dayOfWeek: 0; repeat: false },
ListElement { dayOfWeek: 1; repeat: false },
ListElement { dayOfWeek: 2; repeat: false },
ListElement { dayOfWeek: 3; repeat: false },
ListElement { dayOfWeek: 4; repeat: false },
ListElement { dayOfWeek: 5; repeat: false },
ListElement { dayOfWeek: 6; repeat: false }
]
}
ListElement {
hour: 6
minute: 0
day: 3
month: 8
year: 2018
activated: true
label: "Wake up"
repeat: true
daysToRepeat: [
ListElement { dayOfWeek: 0; repeat: true },
ListElement { dayOfWeek: 1; repeat: true },
ListElement { dayOfWeek: 2; repeat: true },
ListElement { dayOfWeek: 3; repeat: true },
ListElement { dayOfWeek: 4; repeat: true },
ListElement { dayOfWeek: 5; repeat: false },
ListElement { dayOfWeek: 6; repeat: false }
]
}
ListElement {
hour: 7
minute: 0
day: 3
month: 8
year: 2018
activated: false
label: "Exercise"
repeat: true
daysToRepeat: [
ListElement { dayOfWeek: 0; repeat: true },
ListElement { dayOfWeek: 1; repeat: true },
ListElement { dayOfWeek: 2; repeat: true },
ListElement { dayOfWeek: 3; repeat: true },
ListElement { dayOfWeek: 4; repeat: true },
ListElement { dayOfWeek: 5; repeat: true },
ListElement { dayOfWeek: 6; repeat: true }
]
}
ListElement {
hour: 5
minute: 15
day: 1
month: 9
year: 2018
activated: true
label: ""
repeat: false
daysToRepeat: [
ListElement { dayOfWeek: 0; repeat: false },
ListElement { dayOfWeek: 1; repeat: false },
ListElement { dayOfWeek: 2; repeat: false },
ListElement { dayOfWeek: 3; repeat: false },
ListElement { dayOfWeek: 4; repeat: false },
ListElement { dayOfWeek: 5; repeat: false },
ListElement { dayOfWeek: 6; repeat: false }
]
}
ListElement {
hour: 5
minute: 45
day: 3
month: 9
year: 2018
activated: false
label: ""
repeat: false
daysToRepeat: [
ListElement { dayOfWeek: 0; repeat: false },
ListElement { dayOfWeek: 1; repeat: false },
ListElement { dayOfWeek: 2; repeat: false },
ListElement { dayOfWeek: 3; repeat: false },
ListElement { dayOfWeek: 4; repeat: false },
ListElement { dayOfWeek: 5; repeat: false },
ListElement { dayOfWeek: 6; repeat: false }
]
}
}
TumblerDelegate.qml //定义Tumblers的图形布局
//TumblerDelegate 定义了 Tumbler 的图形属性
import QtQuick 2.11
import QtQuick.Controls 2.4
import QtQuick.Controls.Material 2.4
Text {
text: modelData
color: Tumbler.tumbler.Material.foreground
font: Tumbler.tumbler.font
opacity: 1.0 - Math.abs(Tumbler.displacement) / (Tumbler.tumbler.visibleItemCount / 2)
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
输入新警报
//在启动屏幕的底部,您可以看到一个用于添加警报的按钮。 单击它以打开“添加新警报”对话框。
RoundButton {
id: addAlarmButton
text: "+"
anchors.bottom: alarmListView.bottom
anchors.bottomMargin: 8
anchors.horizontalCenter: parent.horizontalCenter
onClicked: alarmDialog.open()
}
新警报的对话框:
//所有字段均使用 Tumbler QML 类型输入。 如果按 OK,则在 Tumblers 中选择的值将写入 alarmModel。
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)
}
}
}
}
}
编辑警报
如果单击特定警报,则可以在详细信息屏幕中对其进行编辑。
//单击警报会将 root.checked 设置为 true,从而使详细信息屏幕的字段可见
visible: root.checked
//如果您希望在其他日子也触发警报,请检查 alarmRepeat。 中继器将为一周中的每一天显示一个可检查的圆形按钮。
Flow {
visible: root.checked && model.repeat
Layout.fillWidth: true
Repeater {
id: dayRepeater
model: daysToRepeat
delegate: RoundButton {
text: Qt.locale().dayName(model.dayOfWeek, Locale.NarrowFormat)
flat: true
checked: model.repeat
checkable: true
Material.background: checked ? Material.accent : "transparent"
onToggled: model.repeat = checked
}
}
}
//如果您修改了警报的描述,之后会在主屏幕中反映出来
TextField {
id: alarmDescriptionTextField
placeholderText: qsTr("Enter description here")
cursorVisible: true
visible: root.checked
text: model.label
onTextEdited: model.label = text
}
删除警报
//详细信息屏幕(见上文)有一个用于删除警报的按钮。 当 onClicked 被发出时,当前的 ListElement 将从 alarmModel 中删除
Button {
id: deleteAlarmButton
text: qsTr("Delete")
width: 40
height: 40
visible: root.checked
onClicked: root.ListView.view.model.remove(root.ListView.view.currentIndex, 1)
}
编译并在Ubuntu运行
修改配色或形状
修改颜色
在qml.qrc文件夹下添加qtquickcontrols2.conf文件及代码:
Item {
[Controls]
Style=Material
[Material]
Theme=Dark
Accent=Green
}
运行可得到
改变形状
修改main.qml文件中的ApplicationWindow中的 width 和 heigh t的参数
运行可得到