澄曜轻剪 v1.0 更新日志
v1.0.0 — 初始版本
新增功能
- 剪贴板历史管理:自动监听系统剪贴板,记录复制内容,支持搜索、批量删除、导出 TXT
- 临时收藏夹:多分组管理,支持新增/重命名/删除收藏项和分组,可设置过期时间
- 全局快捷键:Alt+Shift+V 唤起/隐藏面板、Alt+Shift+X 删除上一条历史、Alt+Shift+S 收藏当前内容
- 文本处理工具栏:去重首尾空格、多行合并单行、提取链接、转大写/小写、首字母大写
- 设置页面:通用设置(开机自启、主题切换)、剪贴板历史(最大条数、自动清理)、收藏夹(过期时间)、快捷键自定义、数据管理(导入/导出)
- 系统托盘:最小化到托盘,右键菜单(显示面板、关于、退出)
- 置顶功能:标题栏置顶按钮,支持窗口始终在最前显示
Bug 修复(开发过程中完整记录)
| # | 问题 | 修复方案 |
|---|---|---|
| 1 | 置顶窗口闪烁 | 改用 setWindowFlag() 替代 setWindowFlags() |
| 2 | 设置页取消置顶后关闭主界面 | 移除 _open_settings 中多余的 setWindowFlags() 调用 |
| 3 | 所有弹窗无图标 | 所有 QDialog 添加 setWindowIcon(QIcon(APP_ICON_PATH)) |
| 4 | 托盘菜单英文 | QAction 全部改为中文文字 |
| 5 | 弹窗按钮英文 (OK/Cancel/Yes/No) | 全部替换为中文自定义按钮(是/否、确定/取消) |
| 6 | 清空全部按钮无反应 | _DraggableTitleBar.mouseReleaseEvent 从 event.accept() 改为 event.ignore(),避免吞噬鼠标释放事件导致 Qt 按钮状态机无法完成点击 |
| 7 | 弹窗被主窗口遮挡无法点击(死锁) | 新增 _show_dialog() 统一方法,临时移除主窗口置顶 + raise_() + activateWindow() |
| 8 | 主窗口关闭按钮图标 | 使用 D:\CYQJ\关闭3.png |
| 9 | 置顶/取消置顶按钮图标 | 分别使用 D:\CYQJ\置顶.png 和 D:\CYQJ\取消置顶.png |
| 10 | 图标按钮有难看的背景色 | 设置 background: transparent; border: none; + setFlat(True) |
| 11 | 收藏夹下拉菜单点击无反应 | showEvent() 中补充调用 _refresh_groups() 初始化分组数据 |
| 12 | 关于对话框 OK 按钮英文 | 从 QMessageBox 改为自定义 QDialog + QPushButton("确定") |
| 13 | 关于对话框快捷键信息过时 | 更新为实际生效的 Alt+Shift+V/X/S |
| 14 | EXE 文件无图标 | spec 文件添加 icon='D:\CYQJ\Chengyao.png' |
| 15 | EXE 文件名为英文 | 改为中文 澄曜轻剪.exe |
核心技术攻坚 — 全局快捷键(经历 15+ 次迭代)
全局快捷键是本次开发过程中遇到的最大技术挑战。Windows 下实现全局热键有多种方案,我们逐一尝试并记录了每种方案的失败原因:
| 尝试方案 | 结果 | 失败原因 |
|---|---|---|
| Qt QAbstractNativeEventFilter + RegisterHotKey(桌面 HWND) | 失败 | WM_HOTKEY 消息发到 explorer.exe 进程的桌面线程,Qt 的 nativeEventFilter 完全收不到 |
| Qt nativeEvent 重写 + 隐藏 QWidget 注册热键 | 失败 | frozen EXE 中 ctypes 创建 Win32 窗口不稳定,CreateWindowExW 返回 NULL (error 1400 无效窗口句柄) |
| pynput GlobalHotKeys | 失败 | frozen EXE 中 Key 枚举对象 identity 不匹配,格式化字符串解析报错 |
| pynput 低级 Listener 手动按键匹配 | 部分成功 | 能收到按键事件但修饰键追踪失败(Python 对象地址比较在 frozen 环境下不可靠 / .name 属性为空) |
| pynput + GetAsyncKeyState API | 部分成功 | 能收到 V 键按下事件但 GetAsyncKeyState 对修饰键返回值全为 False |
| ctypes 自建隐藏窗口 + RegisterClassExW/CreateWindowExW + GetMessageW 消息循环 | 失败 | CreateWindowExW error 1400(无效窗口句柄)、ctypes.wintypes 在 frozen EXE 中不可用(AttributeError)、GetLastError 归属 kernel32 非 user32 |
| Qt 主窗口 winId() + RegisterHotKey + nativeEventFilter | 失败 | RegisterHotKey 注册成功但 WM_HOTKEY 未到达 eventFilter(原因不明,可能与 Qt 消息循环调度有关) |
| keyboard 库 add_hotkey() | 成功 ✓ | 底层使用 SetWindowsHookExW(WH_KEYBOARD_LL) 低级键盘钩子,一行代码搞定,稳定可靠 |
最终方案:使用 Python keyboard 库的 add_hotkey('alt+shift+v', callback) 方法。该库底层通过 Windows SetWindowsHookExW(WH_KEYBOARD_LL) 安装全局低级键盘钩子,不依赖任何窗口句柄或 Qt 消息循环,是目前 Python 生态中最成熟稳定的全局热键解决方案。
默认快捷键说明
| 快捷键 | 功能 |
|---|---|
| Alt+Shift+V | 唤起/隐藏主面板 |
| Alt+Shift+X | 删除上一条剪贴板历史 |
| Alt+Shift+S | 收藏当前剪贴板内容 |
以上快捷键均可在设置页面中自由修改。
评论 0
还没有评论,快来抢沙发吧~