告别PyCharm!用VSCode+PySide6从零搭建一个久坐提醒桌面应用(附完整源码)
用VSCodePySide6打造高效久坐提醒工具从环境配置到功能实现全指南在Python GUI开发领域PyCharm虽然功能全面但其资源占用和启动速度常常让追求效率的开发者望而却步。VSCode凭借其轻量级和强大的扩展性正成为越来越多Python开发者的首选。本文将带你用VSCodePySide6构建一个功能完整的久坐提醒应用涵盖环境配置、UI设计、功能实现到打包发布的完整流程。1. 环境搭建与工具链配置1.1 VSCode Python开发环境准备首先确保已安装最新版VSCode和Python 3.8。在VSCode中安装以下核心扩展Python微软官方Python支持Pylance强大的Python语言服务器Python Indent正确的Python缩进处理Qt for PythonPySide6语法支持创建项目文件夹后初始化虚拟环境python -m venv venv source venv/bin/activate # Linux/macOS venv\Scripts\activate # Windows pip install PySide61.2 Qt Designer集成方案PySide6自带了Qt Designer但需要配置才能在VSCode中高效使用。找到Designer路径import PySide6 print(PySide6.__path__[0] /designer.exe) # Windows建议将Designer添加到系统PATH或创建VSCode任务快速启动。在.vscode/tasks.json中添加{ label: Launch Qt Designer, type: shell, command: ${command:python.interpreterPath}, args: [ -c, \import PySide6; import os; os.startfile(os.path.join(PySide6.__path__[0], designer.exe))\ ], presentation: { reveal: always } }2. UI设计与代码生成工作流2.1 高效UI设计实践启动Qt Designer后设计一个包含以下元素的界面工作时间设置QSpinBox休息时间设置QSpinBox开始按钮QPushButton倒计时显示QLCDNumber休息时锁定输入选项QCheckBox保存为SedentaryReminder.ui后使用PySide6提供的工具转换为Python代码pyside6-uic SedentaryReminder.ui -o ui_SedentaryReminder.py为提高开发效率建议安装Qt for Python Snippets扩展它提供了PySide6常用代码片段。2.2 实时UI预览技巧在VSCode中创建preview.py文件实现UI热重载from PySide6.QtWidgets import QApplication, QMainWindow from ui_SedentaryReminder import Ui_MainWindow import sys import time class PreviewWindow(QMainWindow): def __init__(self): super().__init__() self.ui Ui_MainWindow() self.ui.setupUi(self) if __name__ __main__: app QApplication(sys.argv) while True: window PreviewWindow() window.show() app.processEvents() time.sleep(1) # 每秒检查一次UI文件变化配合VSCode的File Watcher扩展可以实现UI修改后自动转换并预览。3. 核心功能实现3.1 计时器逻辑搭建创建main.py实现倒计时功能from PySide6.QtCore import QTimer, Qt from PySide6.QtWidgets import QApplication, QMainWindow from ui_SedentaryReminder import Ui_MainWindow import sys class MainWindow(QMainWindow): def __init__(self): super().__init__() self.ui Ui_MainWindow() self.ui.setupUi(self) # 初始化计时器 self.work_timer QTimer() self.rest_timer QTimer() self.remaining_seconds 0 # 连接信号槽 self.ui.ok.clicked.connect(self.start_timer) self.work_timer.timeout.connect(self.update_display) self.rest_timer.timeout.connect(self.rest_countdown) def start_timer(self): work_minutes self.ui.workTime.value() self.remaining_seconds work_minutes * 60 self.work_timer.start(1000) # 每秒触发 def update_display(self): self.remaining_seconds - 1 minutes self.remaining_seconds // 60 seconds self.remaining_seconds % 60 self.ui.time.display(f{minutes:02d}:{seconds:02d}) if self.remaining_seconds 0: self.work_timer.stop() self.start_rest_period() def start_rest_period(self): rest_minutes self.ui.restTime.value() self.remaining_seconds rest_minutes * 60 self.rest_timer.start(1000) if self.ui.ifLock.isChecked(): self.lock_input_devices() def rest_countdown(self): self.remaining_seconds - 1 minutes self.remaining_seconds // 60 seconds self.remaining_seconds % 60 self.ui.time.display(f{minutes:02d}:{seconds:02d}) if self.remaining_seconds 0: self.rest_timer.stop() self.unlock_input_devices() self.ui.ok.setEnabled(True)3.2 输入设备控制实现根据操作系统实现设备锁定功能import platform class MainWindow(QMainWindow): # ... 其他代码 ... def lock_input_devices(self): system platform.system() if system Windows: import ctypes ctypes.windll.user32.BlockInput(True) elif system Linux: import subprocess subprocess.run([xinput, set-prop, 所有设备, Device Enabled, 0]) def unlock_input_devices(self): system platform.system() if system Windows: import ctypes ctypes.windll.user32.BlockInput(False) elif system Linux: import subprocess subprocess.run([xinput, set-prop, 所有设备, Device Enabled, 1])注意Windows下需要以管理员权限运行程序才能使用BlockInput API4. 高级功能与优化4.1 系统托盘支持添加托盘图标让应用更专业from PySide6.QtGui import QIcon, QAction from PySide6.QtWidgets import QSystemTrayIcon, QMenu class MainWindow(QMainWindow): def __init__(self): # ... 原有初始化代码 ... # 创建系统托盘 self.tray QSystemTrayIcon(QIcon(icon.png), self) self.tray.setToolTip(久坐提醒) # 创建托盘菜单 tray_menu QMenu() show_action QAction(显示窗口, self) quit_action QAction(退出, self) show_action.triggered.connect(self.show_normal) quit_action.triggered.connect(self.quit_app) tray_menu.addAction(show_action) tray_menu.addAction(quit_action) self.tray.setContextMenu(tray_menu) self.tray.show() def show_normal(self): self.show() self.setWindowState(self.windowState() ~Qt.WindowMinimized) def quit_app(self): self.unlock_input_devices() QApplication.quit()4.2 多线程优化为避免界面卡顿将耗时操作移到工作线程from PySide6.QtCore import QThread, Signal class Worker(QThread): update_signal Signal(int) def __init__(self, duration): super().__init__() self.duration duration def run(self): for i in range(self.duration, -1, -1): self.update_signal.emit(i) self.sleep(1) class MainWindow(QMainWindow): def __init__(self): # ... 原有初始化代码 ... self.worker None def start_timer(self): if self.worker and self.worker.isRunning(): self.worker.terminate() work_minutes self.ui.workTime.value() self.worker Worker(work_minutes * 60) self.worker.update_signal.connect(self.update_display) self.worker.start()5. 打包与分发5.1 使用PyInstaller打包安装打包工具并创建spec文件pip install pyinstaller pyinstaller --name SedentaryReminder --windowed --iconicon.ico --add-data icon.png;. main.py对于更复杂的打包需求可以创建自定义spec文件# sedentary_reminder.spec block_cipher None a Analysis([main.py], pathex[/path/to/your/project], binaries[], datas[(icon.png, .)], hiddenimports[], hookspath[], runtime_hooks[], excludes[], win_no_prefer_redirectsFalse, win_private_assembliesFalse, cipherblock_cipher, noarchiveFalse) pyz PYZ(a.pure, a.zipped_data, cipherblock_cipher) exe EXE(pyz, a.scripts, [], exclude_binariesTrue, nameSedentaryReminder, debugFalse, bootloader_ignore_signalsFalse, stripFalse, upxTrue, consoleFalse, iconicon.ico) coll COLLECT(exe, a.binaries, a.zipfiles, a.datas, stripFalse, upxTrue, upx_exclude[], nameSedentaryReminder)5.2 跨平台打包注意事项不同平台需要特殊处理平台输入锁定方式打包注意事项WindowsBlockInput API需要管理员权限Linuxxinput命令确保xorg-xinput已安装macOSIOHIDPostEvent需要辅助功能权限对于macOS需要在Info.plist中添加keyNSAppleEventsUsageDescription/key string需要控制输入设备以实现休息锁定功能/string