待办事项列表
一个基于 QML 实现的待办事项列表应用程序,演示了如何创建在任何平台上都具有原生外观的应用程序。
“待办事项列表”演示了一个在任何平台上都呈现原生外观的待办事项列表示例应用。该示例可在Qt Design Studio 和Qt Creator 上运行和编辑。它展示了如何创建和使用自定义样式,以及如何通过设置来控制应用的外观和行为。此外,它还演示了如何在代理上实现简单的拖放行为。 该应用程序使用本地存储在设备上保存项目,并使用 XMLHttpRequest 从公共 API 检索数据(“随机任务”功能)。视图由StackView 组件控制。
运行示例
您可以通过以下方式运行示例:
- Qt Creator
打开Welcome 模式,并从Examples 中选择该示例。有关更多信息,请参阅Qt Creator :教程:构建和运行。
- Qt Extension for Visual Studio Code
在Command Palette 中运行Qt: Open Qt examples 命令,并从列表中选择该示例。有关更多信息,请参阅《Qt Extension for Visual Studio Code :教程:构建和运行》。






选择应用样式
该应用程序根据目标平台支持不同的样式。CustomStyle、Basic、Material 和 Universal 样式在每个平台(Windows、Android、iOS、macOS)上均可用。 Windows 样式仅在 Windows 系统上可用,iOS 样式仅在 iOS 系统上可用。可用样式列表位于“SettingsView ”的“Style”子页面中。您可以在同一位置更改当前使用的样式。应用更改后需要重启应用。应用将通过“ToolTip ”提示向用户通知此操作。
更改主题
每种样式均支持深色和浅色主题。 可在“SettingsView ”的“Theme”子页面中更改主题。并非所有样式都允许用户手动更改主题,例如在 iOS 系统上此选项不可用。在此情况下,主题将根据系统默认设置进行调整。首次启动应用时,将使用系统主题。
通过应用设置控制应用行为
可通过SettingsView 更改应用的行为和样式。这些设置允许用户更改:
- 样式
- 主题
- 字体大小
- 任务最大数量
- 是否自动删除已完成的任务
任务列表实现
该应用程序包含三个不同的列表:
- 今日任务列表 → 截止日期为今天的任务。
- 本周任务列表 → 截止日期在未来七天内的任务。
- 后续任务 → 不属于上述列表的任务。
任务在应用程序启动时会被分配到各个列表模型中。当然,任务在运行时(当其截止日期发生变化时)可以在列表模型之间迁移。单个列表的定义在TasksList.qml 和TasksListForm.ui.qml 中完成,实例的创建则在TasksListsView.qml/TasksListsViewForm.ui.qml 中进行。
ListModel {
id: todayTasksListModel
}
ListModel {
id: thisWeekTasksListModel
}
ListModel {
id: laterTasksListModel
}
Column {
id: column
anchors.fill: parent
spacing: 14
TasksList {
id: todayTasks
width: column.width
maxHeight: 180
listModel: todayTasksListModel
headerText: qsTr("Today")
tasksCount: todayTasksListModel.count
}
TasksList {
id: thisWeekTasks
width: column.width
maxHeight: column.height - y - 60
listModel: thisWeekTasksListModel
headerText: qsTr("This week")
tasksCount: thisWeekTasksListModel.count
}
TasksList {
id: laterTasks
width: column.width
maxHeight: column.height - y
listModel: laterTasksListModel
headerText: qsTr("Later")
tasksCount: laterTasksListModel.count
}
}在TasksListsView.qml 和Component.onCompleted 中,将数据填充到列表模型中。
function createTasksLists() : void {
var tasks = Database.getTasks()
var currentDate = new Date()
var format = Qt.locale().dateFormat(Locale.LongFormat)
var dateStr = currentDate.toLocaleDateString(Qt.locale(),format)
tasks.forEach( function(task){
if (task.date === dateStr) {
todayTasksModel.append(task)
} else if (checkThisWeekDate(task.date)) {
thisWeekTasksModel.append(task)
} else {
laterTasksModel.append(task)
}
})
}
Component.onCompleted: createTasksLists()滑动、拖拽和放下行为
列表视图使用TasksListDelegate 作为委托。该委托是一个SwipeDelegate ,它允许用户通过滑动项目来将其高亮显示(该项目将移至列表顶部)或将其移除。 此外,用户还可以将任务标记为已完成(该项目将被移至列表底部),或者通过拖放将项目移动到列表中的特定位置。这些行为的实现位于TasksListDelegate.qml 中。
本地存储的使用
本地存储用于将任务项读写到 SQLite 数据库中。此功能及其他辅助函数的实现位于Database.qml 中,该文件定义了一个单例对象。
property var _db
function _database() {
if (_db) return _db
try {
let db = LocalStorage.openDatabaseSync("ToDoList", "1.0", "ToDoList app database")
db.transaction(function (tx) {
tx.executeSql(`CREATE TABLE IF NOT EXISTS tasks (
task_id INTEGER PRIMARY KEY AUTOINCREMENT,
task_name,
task_dueDate TEXT,
task_dueTime TEXT,
task_notes TEXT,
done INTEGER,
highlighted INTEGER
)`);
})
_db = db
} catch (error) {
console.log("Error opening databse: " + error)
};
return _db
}
function addTask(taskName, taskDueDate, taskDueTime, taskNotes, taskDone, taskHighlighted) {
let results
root._database().transaction(function(tx){
tx.executeSql(`INSERT INTO tasks (task_name, task_dueDate, task_dueTime,
task_notes, done, highlighted) VALUES(?,?,?,?,?,?);`,
[taskName, taskDueDate, taskDueTime, taskNotes, taskDone, taskHighlighted])
results = tx.executeSql("SELECT * FROM tasks ORDER BY task_id DESC LIMIT 1")
})
return results.rows.item(0).task_id
}使用 XMLHttpRequest 从公共 API 获取数据
XMLHttpRequest 用于向某些公共 API 发送请求并获取响应数据。该应用程序使用boredapi,该 API 可返回一个待处理的随机任务。随后,该任务将被添加到“今日任务”列表中。
function sendHttpRequest() : void {
var http = new XMLHttpRequest()
var url = "https://www.boredapi.com/api/activity";
http.open("GET", url, true);
http.setRequestHeader("Content-type", "application/json");
http.setRequestHeader("Connection", "close");
http.onreadystatechange = function() {
if (http.readyState == 4) {
if (http.status == 200) {
let object = JSON.parse(http.responseText.toString());
let currentDate = new Date()
let format = Qt.locale().dateFormat(Locale.LongFormat)
addTask(todayTasksModel, object.activity,
currentDate.toLocaleDateString(Qt.locale(), format), "","")
} else {
console.log("Failed to fetch a random TODO item; the API provider might be down")
}
}
}
http.send();
}源文件
另请参阅 所有 Qt 示例以及Qt Quick 示例和教程。
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.