1. 为什么我们需要一个久坐提醒工具?
作为一个长期伏案工作的程序员,我深刻理解久坐带来的危害。腰酸背痛、颈椎不适、视力下降这些问题都曾困扰过我。医学研究表明,连续坐姿超过1小时就会对血液循环造成影响,增加心血管疾病风险。而一个简单的定时提醒工具,就能有效帮助我们养成定时起身活动的习惯。
Pyside6作为Qt for Python的官方绑定库,非常适合用来开发这类轻量级桌面应用。它不仅继承了Qt强大的跨平台能力,还提供了Python简洁的语法特性。相比其他GUI框架,Pyside6有以下几个优势:
- 完善的文档和社区支持
- 丰富的UI组件库
- 可视化设计工具(Qt Designer)
- 原生支持多线程和信号槽机制
这个项目我们将从零开始,开发一个具备完整功能的久坐提醒工具。它不仅能显示倒计时,还能自定义工作和休息时长,甚至可以在休息时锁定键盘鼠标(当然是在用户自愿的前提下)。下面让我们一步步来实现它。
2. 开发环境准备与基础配置
2.1 安装Pyside6
首先确保你已经安装了Python 3.6或更高版本。我推荐使用虚拟环境来管理项目依赖,这样可以避免包冲突问题。创建并激活虚拟环境的命令如下:
python -m venv venv source venv/bin/activate # Linux/Mac venv\Scripts\activate # Windows接下来安装Pyside6:
pip install pyside6注意:包名是pyside6而不是Pyside6,Python包通常使用小写命名规范。
安装完成后,可以检查下是否安装成功:
import PySide6 print(PySide6.__version__)2.2 配置开发工具
我强烈推荐使用Qt Designer来设计界面,它提供了可视化的拖拽操作,能大大提高开发效率。安装Pyside6后,Designer工具通常位于:
- Windows:
venv\Lib\site-packages\PySide6\designer.exe - Mac/Linux:
venv/lib/python3.x/site-packages/PySide6/designer
为了方便使用,你可以创建一个快捷方式或者将其添加到系统PATH中。另外,建议使用PyCharm或VS Code作为代码编辑器,它们对Python和Qt开发都有很好的支持。
3. 设计久坐提醒工具的界面
3.1 使用Qt Designer创建UI
启动Qt Designer后,选择"Main Window"模板开始设计。我们的久坐提醒工具需要以下元素:
- 工作时间设置(SpinBox)
- 休息时间设置(SpinBox)
- 开始按钮(PushButton)
- 倒计时显示(LCDNumber)
- 休息时锁定输入的选项(CheckBox)
在设计时要注意几点:
- 使用布局管理器(Layouts)而不是固定位置,这样窗口缩放时组件能自动调整
- 为每个组件设置合理的objectName,方便后续代码引用
- 适当使用间隔器(Spacers)让界面更美观
完成设计后,将文件保存为sedentary_reminder.ui。这个XML格式的文件描述了界面结构,但还不能直接使用。
3.2 将UI文件转换为Python代码
Pyside6提供了pyside6-uic工具来转换UI文件:
pyside6-uic sedentary_reminder.ui -o ui_sedentary_reminder.py生成的Python文件包含一个Ui_MainWindow类,它实现了我们设计的界面。这个文件一般不需要手动修改,因为每次设计变更后都需要重新生成。
提示:可以将这个命令写成脚本或配置到IDE的构建任务中,简化开发流程。
4. 实现应用逻辑功能
4.1 创建主程序框架
新建一个main.py文件,建立基本的应用框架:
from PySide6.QtWidgets import QApplication, QMainWindow from ui_sedentary_reminder import Ui_MainWindow class MainWindow(QMainWindow): def __init__(self): super().__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) # 初始化设置 self.work_duration = 45 # 默认工作时间45分钟 self.rest_duration = 5 # 默认休息时间5分钟 self.is_working = True self.remaining_time = self.work_duration * 60 # 转换为秒 # 连接信号槽 self.connect_signals() def connect_signals(self): """连接所有UI信号到对应的槽函数""" self.ui.start_btn.clicked.connect(self.start_timer) self.ui.work_time_spin.valueChanged.connect(self.update_work_time) self.ui.rest_time_spin.valueChanged.connect(self.update_rest_time) if __name__ == "__main__": app = QApplication([]) window = MainWindow() window.show() app.exec()4.2 实现计时器功能
我们需要使用QTimer来实现倒计时功能。在MainWindow类中添加以下方法:
from PySide6.QtCore import QTimer class MainWindow(QMainWindow): # ... 之前的代码 ... def start_timer(self): """启动或暂停计时器""" if not hasattr(self, 'timer'): self.timer = QTimer() self.timer.timeout.connect(self.update_time) if self.timer.isActive(): self.timer.stop() self.ui.start_btn.setText("开始") else: self.timer.start(1000) # 每秒触发一次 self.ui.start_btn.setText("暂停") self.update_display() def update_time(self): """更新剩余时间""" self.remaining_time -= 1 if self.remaining_time <= 0: self.switch_mode() self.update_display() def switch_mode(self): """切换工作/休息模式""" self.is_working = not self.is_working if self.is_working: self.remaining_time = self.work_duration * 60 self.show_message("工作时间到!") else: self.remaining_time = self.rest_duration * 60 self.show_message("请休息一下!") if self.ui.lock_check.isChecked(): self.lock_input() def update_display(self): """更新LCD显示""" minutes = self.remaining_time // 60 seconds = self.remaining_time % 60 self.ui.lcd_display.display(f"{minutes:02d}:{seconds:02d}")4.3 添加额外功能
为了让工具更实用,我们可以添加以下功能:
- 休息时锁定输入(需要管理员权限):
import ctypes import sys def lock_input(self): """锁定键盘鼠标输入""" if sys.platform == 'win32': ctypes.windll.user32.BlockInput(True) # 其他平台实现略...- 系统托盘图标(让应用最小化到托盘):
from PySide6.QtGui import QIcon def create_tray_icon(self): """创建系统托盘图标""" self.tray_icon = QSystemTrayIcon(self) self.tray_icon.setIcon(QIcon("icon.png")) menu = QMenu() show_action = menu.addAction("显示") quit_action = menu.addAction("退出") show_action.triggered.connect(self.show_normal) quit_action.triggered.connect(self.quit_app) self.tray_icon.setContextMenu(menu) self.tray_icon.show()- 定时提醒通知:
from PySide6.QtWidgets import QMessageBox def show_message(self, text): """显示提醒消息""" msg = QMessageBox() msg.setWindowTitle("提醒") msg.setText(text) msg.exec_()5. 打包与分发应用
5.1 使用PyInstaller打包
为了让没有Python环境的用户也能使用,我们可以用PyInstaller打包应用:
pip install pyinstaller pyinstaller --onefile --windowed --icon=app.ico main.py这会在dist目录下生成可执行文件。对于更专业的打包,可以考虑使用NSIS或Inno Setup创建安装程序。
5.2 跨平台注意事项
Pyside6应用本质上是跨平台的,但需要注意:
- 路径分隔符使用
/或os.path.join - 平台特定功能(如输入锁定)需要条件判断
- 图标和资源文件要包含在打包中
6. 实际使用中的优化建议
经过几周的实测,我发现以下几个优化点能显著提升使用体验:
渐强式提醒:休息时间快结束时,音量逐渐增大或闪烁频率加快,给用户一个缓冲期。
智能跳过:当检测到用户已经离开(通过摄像头或鼠标移动),可以自动跳过当前提醒。
数据统计:记录每日坐姿时间,生成健康报告。
云端同步:通过简单的Web服务同步多设备间的设置和状态。
实现这些功能需要引入更多模块,比如:
- PyAudio用于声音控制
- OpenCV用于用户检测
- SQLite本地存储数据
- Requests进行网络通信
这个项目很好地展示了如何用Pyside6解决实际问题。从简单的UI展示到完整的应用开发,每一步都能学到实用的GUI编程技巧。最重要的是,它能真正改善我们的工作习惯和健康状况。