一、前言
最近大论文已经修改的差不多了,即将提交盲审,所以接下来的一个月时间算是一段比较空闲的日子吧。
也不知道是不是熬夜熬多了,最近记性真不好,前一秒还记着要干什么,后面就忘了。想过用便签记录待办事项,把便签贴到实验室的电脑上,这样每次就能看到了,时刻提醒自己处理事情。但是,咱程序员天生就不会用纸记录事情😎😎(好吧,事实是我没有纸质便签,还得买,有那钱咱买瓶脉动喝不香么🤷♂️🤷♂️),所以,必须发挥咱代码搬运工的优势,写一个待办事项软件!!!
二、构思
我的想法是这样的,就像便签能够贴在任何地方一样,该软件要能够贴在电脑桌面上,像许多桌面管理软件一样,这个软件不受电脑显示桌面或者Win+D等的控制,始终贴在桌面上,这样无论我如何操作,每次我都能看见我的待办事项,这是最基本的,像是一个”电子便签“,可以记录事情,然后贴到桌面的某个地方。下文统称这个软件为TODO。
当然,作为一个信息记录软件,基本的信息编辑与删除功能是必需的,此外,TODO应该还要有比较好看的界面和一定的UI用户自定义功能,毕竟是个要贴在电脑桌面上的软件,界面难看的话天天看也难免不闹心🤣🤣。
现在一个最基本的待办事项记录软件TODO已经构思的差不多了,很简单,接下来着手实现。
三、设计与实现
TODO软件的实现使用Qt+Cpp+SQLite框架,SQLite负责数据的持久化。
3.1 数据库设计
这部分貌似没啥可说的,TODO目前的功能很简单,数据库主要用来存储待办事项数据,谈不上什么数据库设计。简单提一下,由于TODO中数据主要是文字信息的存储,所以选择使用SQLite数据库,设计的表记录包含5个字段,数据库主键id,待办事项标题,待办事项内容,待办事项的创建时间,标记待办事项是否完成的flag。
id | note_title | note_context | note_time | is_fin |
---|---|---|---|---|
int primary key | varchar(30) | varchar(150) | char(20) | int |
主键 | 标题 | 内容 | 创建时间 | 完成标记 |
3.2 TODO功能实现
3.2.1 无边框界面设计实现
界面设计其实没啥可说的,但是实现的时候遇到一个问题还困惑了我好久,在此浅浅提一下,TODO界面采用无边框的样式,同时隐藏了任务栏图标显示,对于这种Tool
型的窗口直接使用close()
方法是关不掉的(Tool
作为工具窗口,一般的关闭事件,系统认为只是隐藏而已,所以不是真正的关闭),如果真正退出应用程序,需要重载QWidget
的close()
函数,在其中加入QApplication::quit()
。
在设置无边框Tool窗口时使用的所有Dialog
均需要指定一个parent
对象,如果不指定,为nullptr
,则作为顶层窗口,一旦这个顶层窗口关闭后(Dialog
能够真正的关闭,而不是隐藏),整个程序就会关闭,包括我们设置的无边框Tool
窗口。
1 | this->setWindowFlags(Qt::FramelessWindowHint | Qt::Tool | Qt::X11BypassWindowManagerHint); |
3.2.2 TODO开机自启动
设置TODO程序开机自启动是通过写注册表的方式实现的。注册表中设置自启动时采用key-value
的形式,key
为自启动的软件名称,value
为自启动的软件路径。通常将value
设置为软件可执行文件的路径,但是通过这种方法设置的开机自启动会导致程序启动时读取配置文件或者其它文件失败,因为开机启动命令是CMD命令,是System32进程启动可执行程序,导致可执行程序路径错误。
可行的解决方法是:
- 创建快捷方式,开机自启动的
value
是快捷方式的路径。 - 创建bat脚本,开机自启动的
value
是脚本的路径。
1 | HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run |
第一个为所有用户登录时启动的项目,第二个是当前用户登录时启动的项目。编辑第一个注册表需要管理员权限,因此使用第二个。
快捷方式设计开机自启动实现如下:
1 | QSettings reg("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::NativeFormat); |
设置开机自启动的bat脚本如下:
1 | @echo off |
3.2.3 待办事项列表设计实现
TODO软件待办事项是放在QListWidget
容器中的,该容器支持对容器里面的Item
进行排序,排序规则可自定义。TODO软件的待办事项需要按照已完成/未完成进行排序,同时已完成/未完成的两组列表中需要按照创建时间的先后进行排序。
实现QListWidget
自定义排序可以通过重载QListWidgetItem
类的<
运算符。实现方式如下:
1 | struct SortWeight |
1 | bool compare(const QString &str1, const QString &str2) |
1 | class ListWidgetItem : public QListWidgetItem |
3.2.4 TODO日志系统实现
软件的日志系统是记录分析软件运行错误的重要部分,是必不可少的。
TODO软件的日志系统使用Log4QT搭建。
3.4 TODO界面
TODO主界面如下:
软件设置界面如下: