隆重推出:考勤卡
创建工时卡 2.0
隆重推出 Timecard 2.0!
我至今仍记得我的第一个真正的软件项目。那是在2011年,当我第一次学习使用Visual Basic .NET进行编程时,我创建了一个小应用程序,用来跟踪我在各项任务上花费的时间。
它的界面不算最美观——我当时有点太沉迷于创建对话框的功能了——但它运行良好,而且实际上并没有什么重大bug。我非常喜欢它!
但随着时间的推移,.NET 的依赖项逐渐过时。我转而使用 Linux 系统,最终在某种情况下丢失了源代码和官方安装程序,而我至今仍然记不清具体原因。
多年来,我一直在寻找一款像我挚爱的 Timecard 一样流畅易用的软件。最接近的是Project Hamster,它曾经非常适合我,直到开发者对这个项目失去了兴趣。
最终,这个月我意识到:“嘿,我正在写这本《极其简单的 Python》书,但我还没有发布过一个完整的 Python 应用程序!”
于是我坐下来,启动了 Visual Studio Code,开始工作。
创建工时卡 2.0
从零开始重写 Timecard 意味着要彻底重新构思这个程序。我没有任何可以参考的资料:没有截图,没有 v1.0 的运行副本,也没有之前的源代码。
我一直在深入研究 Qt 5 和 PySide2,所以它自然而然地成为了我开发 GUI 的首选,不过最主要的原因是我知道 Qt 5 应用是可以打包的。2018年的大部分时间里,我都在尝试打包我的益智游戏 Omission(至今尚未发布),但由于 Kivy 及其依赖项的一些奇怪问题,最终以失败告终。(我现在正在用 PySide2 重写这款游戏。)
无对话
从早期开始,我就对对话框失去了兴趣,但它们仍然是桌面用户体验设计中非常常见的隐喻!我计划只使用一两个对话框来确认关键操作,例如删除时间日志条目。
但编码不到一个小时,我就遇到了QTBUG-56893。我曾短暂地考虑过暂停项目,直到这个 bug 被修复,但我的急躁最终还是占了上风。
“除了对话框,我还能用什么代替呢?”我问自己。片刻之后,我决定采用响应式单窗口界面来解决问题,而且会让人耳目一新!点击“停止”或“重置”这类“吓人”的按钮时,这两个按钮会以截然不同的方式发生变化,提示用户确认或取消操作。
一旦我决定采用自适应界面,其余的设计决策就很快水到渠成了。计时器及其控件是应用程序最重要的部分,因此它们会始终显示在最上方。窗口的其余部分会根据模式而变化,底部有四个友好的按钮。切换到“设置”模式会改变界面的主要部分,“设置”按钮也会变成“记录”,以便返回默认的时间记录视图。
文件
时间卡需要使用文件来保存设置和时间日志。与我的程序第一个版本需要手动导出不同,我希望新版时间卡能够自动将更改保存到文件中,而无需用户进行任何操作。
项目的这一部分实际上占用了我大量的时间,但这也好,因为我正在撰写文章和《Dead Simple Python》一书中关于处理文件的章节!
系统托盘
我最需要的功能之一就是系统托盘图标。我有个坏习惯,总是会不小心关闭重要的窗口,所以大多数计时应用对我来说都不好用!Timecard 的窗口关闭后,应该默认隐藏在系统托盘中。退出时,可以通过界面上的“退出”按钮,点击后会弹出确认提示。(当然,这个隐藏到托盘的默认行为可以在设置里更改。)
静态类
如果你以前编写过界面代码,就会知道对象既是福音也是祸根。封装对于确保组件与其关联数据和特殊功能保持一致非常有用。
另一方面,实例呢?唉。大多数情况下,比如时间显示控件,你只需要一个实例,而所有与它交互的组件都需要访问同一个实例。处理这种情况的方法有很多,但大多数都很糟糕:比如所有组件都使用全局实例、单例模式(拜托,千万别用!),或者使用一个“上帝类”来处理组件之间的通信。没错,以上这些我都试过……但我一个都不推荐。
对于 Timecard 类,我非常清楚哪些对象只需要存在一次,所以我将它们编写成静态类。通过使用@classmethod类属性,我避免了管理实例的繁琐工作,同时又没有放弃面向对象编程提供的封装和命名空间等优点。
我知道有些 Python 开发人员可能会看到这篇文章后对着屏幕大喊大叫,但是你知道吗?类在这方面真的非常有效!
- 代码简洁明了,组织结构良好,职责划分清晰。
- 没有全局变量。所有变量都使用命名空间。
- 导入语句显而易见。
- 可读性真棒!
我已经不得不重新查看代码来修复一些错误,但每次我只需要花一点时间就能弄清楚问题出在哪里。
我相信还有一些机会可以进一步重构代码,但我一想到如果当初没有使用类,将会面临怎样的噩梦,就不寒而栗。
隆重推出 Timecard 2.0!
我为这款应用感到无比自豪,我已经把它融入到我的工作流程中,提高了工作效率。
要开始记录,只需点击即可Start。您可以在What are you doing?计时器正下方的文本框中描述您当前的活动。您可以使用按钮暂停当前计时器Pause,该按钮会变成Resume暂停按钮。
要停止计时器并保存或重置它,请点击Stop,然后它会变成Confirm Stop按钮(或者,您可以点击Resume取消停止)。控制按钮会再次变为Reset和Save,分别用于放弃您的时间或将其保存到日志中。
开始时间将用作时间戳,活动备注取自您在计时器下方输入的消息。
关闭窗口只会将其隐藏,Timecard 仍会在系统托盘中运行。点击图标可显示当前计时器持续时间,并允许您暂停和恢复计时。(为防止误操作,只能在主窗口中停止计时。)
Quit只要计时器正在运行或未保存,该选项就会被禁用,以确保您不会因为误点菜单而意外浪费时间。
在“设置”视图中,您可以更改日志文件的保存位置。更新此设置并单击Save即可立即打开新文件,因此维护和切换日志文件非常方便。(我计划稍后让这个操作更加便捷。)
您还可以修改日志视图中显示的时间戳格式,但这不会影响文件解析输出。您还可以将持续时间显示为十进制小时,如果您需要将时间输入到那些烦人的工作时间报告应用程序中,这将非常方便。(我讨厌每次都要拿出计算器来计算十进制小时。谁会这么想啊?)
下载
好了,就说这么多吧。你可能想开始用它了,对吧?
目前只能通过 PyPI 安装,不过我正在努力将其打包成其他格式。但如果你pip手头有 PyPI,安装起来就非常简单!
pip install --user timecard-app
要启动程序,只需运行:
timecard-app
如需了解更多关于 Timecard 的信息,包括我计划在未来推出的功能,请访问官方页面和GitHub。欢迎提交反馈、问题报告和拉取请求。
文章来源:https://dev.to/codemouse92/introducing-timecard-2e2d



