1. 项目概述:用Qt打造高效待办事项记录器
最近在整理个人时间管理工具时,发现市面上大多数待办事项软件要么功能臃肿,要么缺乏自定义能力。作为Qt开发者,我决定用这个经典的跨平台框架亲手打造一个轻量级解决方案。这个待办事项记录器不仅实现了基础的任务管理功能,还深度整合了Qt的信号槽机制和模型/视图架构,特别适合想要学习Qt实际应用的中级开发者参考。
选择Qt作为开发框架主要基于三个考量:首先,其跨平台特性让应用可以无缝运行在Windows、macOS和Linux系统上;其次,模型/视图架构非常适合处理待办事项这类结构化数据;最后,Qt Designer提供的可视化设计能力能大幅提升UI开发效率。这个项目完整覆盖了从界面设计到数据持久化的全流程,涉及QWidgets、QStandardItemModel、QSettings等核心组件的实战应用。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 开发环境准备与配置
2.1 Qt开发环境搭建
推荐使用Qt 5.15 LTS版本(当前最新为5.15.2),这是长期支持版本中功能最完善的。安装时务必勾选以下组件:
- Qt 5.15.2 → MSVC 2019 64-bit(Windows平台)
- Qt Creator 4.11.0以上版本
- Qt Designer(内置界面设计工具)
- Qt Charts(可选,用于后期数据可视化扩展)
对于国内开发者,建议使用清华镜像源加速下载:
bash复制# 设置临时镜像源(Linux/macOS)
export QT_MIRROR=https://mirrors.tuna.tsinghua.edu.cn/qt
# Windows可在安装器高级选项中配置
注意:安装完成后若遇到"this application failed to start because no qt platform plugin could be initialized"错误,通常是因为环境变量未正确配置。解决方案是将
Qt安装目录/版本号/编译器版本/plugins路径添加到系统PATH中。
2.2 项目结构设计
创建纯Qt Widgets Application项目(非QML),采用以下目录结构:
code复制TodoList/
├── include/ # 头文件
├── src/ # 源文件
├── resources/ # 资源文件
│ ├── icons/ # 图标素材
│ └── styles/ # QSS样式表
└── forms/ # Qt Designer生成的.ui文件
在.pro文件中添加必要的模块依赖:
qmake复制QT += core gui widgets
CONFIG += c++11
3. 核心功能实现详解
3.1 数据模型设计
采用QStandardItemModel作为基础模型,扩展自定义角色实现优先级标记:
cpp复制class TodoModel : public QStandardItemModel {
Q_OBJECT
public:
enum CustomRoles {
PriorityRole = Qt::UserRole + 1,
DueDateRole,
CompletedRole
};
explicit TodoModel(QObject *parent = nullptr);
QVariant data(const QModelIndex &index, int role) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
};
模型数据持久化使用QSettings存储为INI格式:
cpp复制void saveToSettings(QSettings &settings) {
settings.beginWriteArray("todos");
for(int i = 0; i < rowCount(); ++i) {
settings.setArrayIndex(i);
settings.setValue("title", item(i)->text());
settings.setValue("priority", item(i)->data(PriorityRole));
}
settings.endArray();
}
3.2 主界面开发
使用Qt Designer设计主界面(mainwindow.ui),关键组件包括:
- QListView:显示待办事项列表
- QLineEdit:任务输入框
- QToolButton:添加/删除/完成操作按钮
- QComboBox:优先级筛选器
通过提升为自定义视图类实现双击编辑:
cpp复制class TodoView : public QListView {
Q_OBJECT
protected:
void mouseDoubleClickEvent(QMouseEvent *event) override {
QModelIndex index = indexAt(event->pos());
if(index.isValid()) {
edit(index);
}
}
};
3.3 功能逻辑实现
任务添加的槽函数实现示例:
cpp复制void MainWindow::onAddClicked() {
QString text = ui->lineEdit->text().trimmed();
if(!text.isEmpty()) {
QStandardItem *item = new QStandardItem(text);
item->setData(ui->priorityCombo->currentData(), TodoModel::PriorityRole);
item->setData(QDate::currentDate().addDays(3), TodoModel::DueDateRole); // 默认3天后到期
model->appendRow(item);
ui->lineEdit->clear();
}
}
实现按优先级筛选的代理模型:
cpp复制class PriorityFilterProxy : public QSortFilterProxyModel {
int m_priority = -1;
public:
void setPriorityFilter(int priority) {
m_priority = priority;
invalidateFilter();
}
protected:
bool filterAcceptsRow(int source_row, const QModelIndex &) const override {
if(m_priority == -1) return true;
return sourceModel()->index(source_row, 0)
.data(TodoModel::PriorityRole).toInt() == m_priority;
}
};
4. 进阶功能扩展
4.1 拖拽排序实现
启用自定义拖拽操作需要重写视图的拖拽事件:
cpp复制void TodoView::dragMoveEvent(QDragMoveEvent *e) {
if(e->mimeData()->hasFormat("application/x-todomodeldatalist")) {
e->acceptProposedAction();
}
}
void TodoView::dropEvent(QDropEvent *e) {
QByteArray itemData = e->mimeData()->data("application/x-todomodeldatalist");
// 自定义拖拽位置处理逻辑...
}
4.2 样式美化技巧
使用QSS实现斑马线效果和优先级颜色标记:
css复制QListView::item {
border-bottom: 1px solid #eee;
padding: 8px;
}
QListView::item[priority="1"] { /* 高优先级 */
background: #fff0f0;
}
QListView::item[priority="2"] { /* 中优先级 */
background: #fff9e6;
}
QListView::item:alternate { /* 隔行变色 */
background: #f9f9f9;
}
4.3 多线程数据加载
对于大量任务项,使用QRunnable实现后台加载:
cpp复制class DataLoader : public QObject, public QRunnable {
Q_OBJECT
public:
void run() override {
// 耗时加载操作...
emit loadFinished(data);
}
signals:
void loadFinished(TodoData data);
};
5. 常见问题与调试技巧
5.1 典型问题解决方案
-
中文乱码问题:
在main.cpp中添加编码设置:cpp复制QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")); -
信号槽连接失败:
使用新式语法确保编译期检查:cpp复制connect(button, &QPushButton::clicked, this, &MainWindow::onButtonClicked); -
界面卡顿:
对于超过1000项的列表,改用QAbstractItemModel实现懒加载。
5.2 调试输出优化
在Qt Creator中配置自定义格式化输出:
plaintext复制类型 格式 描述
QDate %{yyyy-MM-dd} ISO格式日期
QTime %{hh:mm:ss.z} 带毫秒时间
QDateTime %{timestamp} 时间戳
5.3 内存泄漏检测
在.pro文件中启用内存调试:
qmake复制CONFIG += debug
DEFINES += QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII
使用valgrind检测(Linux/macOS):
bash复制valgrind --tool=memcheck --leak-check=full ./todo-list
6. 项目构建与部署
6.1 跨平台编译配置
在.pro文件中添加平台条件判断:
qmake复制win32 {
RC_ICONS = resources/icons/app.ico
LIBS += -luser32
}
macx {
ICON = resources/icons/app.icns
QMAKE_INFO_PLIST = resources/mac/Info.plist
}
6.2 打包发布指南
使用windeployqt工具(Windows):
bash复制windeployqt --compiler-runtime --qmldir qml/ todo-list.exe
创建macOS应用包:
bash复制macdeployqt TodoList.app -dmg -always-overwrite
6.3 安装程序制作
使用NSIS(Windows)或macdeployqt(macOS)生成安装包。对于Linux系统,推荐制作.deb或.rpm包:
bash复制# 创建deb包基本结构
mkdir -p package/DEBIAN
cp control package/DEBIAN/
dpkg-deb --build package todo-list.deb
这个待办事项记录器项目虽然规模不大,但完整覆盖了Qt开发的典型技术栈。在实际开发过程中,我特别推荐使用Qt Creator的调试工具来观察信号槽的触发顺序,这对理解Qt的事件机制非常有帮助。另外,当处理大量数据项时,可以考虑采用QAbstractItemModel的懒加载模式来提升性能。
