# todo-widget **Repository Path**: MyClown/todo-widget ## Basic Information - **Project Name**: todo-widget - **Description**: 桌面待办组件 - **Primary Language**: Python - **License**: GPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-18 - **Last Updated**: 2026-10-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 桌面待办小组件 Windows 桌面悬浮待办清单,无边框透明背景、置顶、可拖拽位置和尺寸,iconfont 统一图标风格,数据存储 MySQL 5.7(连不上自动回退本地 JSON)。 ## 快速开始 **正常情况:直接双击 `run.bat`** 它会自己找 Python(优先 `.\python\python.exe`,其次系统里的 `python`), 检查 `pyqt5` / `pymysql`,缺了会自动 `pip install`,然后启动小组件。 启动后有个菜单:`1` 正常启动、`2` 后台启动(不带黑窗口)、`3` 打开日志。 **不想开黑窗口:双击 `后台启动.vbs`** 用 `pythonw.exe` 启动,屏幕上一个窗口都不会出现,小组件直接挂桌面上。 它会等 3 秒读日志确认启动成功;失败会弹窗提示并自动打开日志文件。 注意:后台启动看不到任何报错,出问题只能翻日志,所以第一次建议先用 `run.bat` 跑通。 **开机自动启动:双击 `开机自启.vbs`** 点一次 = 打开自启,再点一次 = 关闭自启。它只是在「启动」文件夹(`Win+R` 输入 `shell:startup` 可看到)里放/删一个快捷方式,不写注册表,想关随时能关。 **没有 Python:先跑一次安装脚本** 1. 右键 `setup.ps1` → 使用 PowerShell 运行 (或在 PowerShell 窗口里:`powershell -ExecutionPolicy Bypass -File setup.ps1`) 2. 等它自动下载便携版 Python 3.11 到 `.\python` 目录,并装好依赖 3. 双击 `run.bat` `setup.ps1` 可选参数: - 不带参数 → 下载便携版 Python,不需要管理员权限、不污染系统 - `-System` → 改用机器上已安装的 Python,不下载任何东西 > 如果 PowerShell 禁止运行脚本,先执行: > `Set-ExecutionPolicy -Scope CurrentUser RemoteSigned` > 国内网络:脚本已内置镜像回退(Python 包用 npmmirror,pip 用清华源), > 一般不用手动设置。 ## 出错了怎么办 - **黑框一闪就没**:说明启动就崩了。直接双击 `run.bat`,它会显示 `todo_widget_error.log` 里的完整报错;该文件也在小组件目录下,可单独打开看。 - **后台启动后桌面空空如也**:`后台启动.vbs` 本身会弹一个错误框。没弹窗的话 手动 `notepad todo_widget_debug.log`,看最后一行是不是 `window shown, entering event loop`。 后台启动看不到任何报错,日志是唯一线索。 - **桌面上出现两个待办框**:说明起了两个进程。程序内置了单实例锁(用 `widget_pid.txt` 记录 进程号,启动时 `OpenProcess` 探测该进程是否还活着;进程死了锁会自动清掉), 正常情况第二个会自动退出。如果仍出现两个,或日志里反复出现 `another instance is already running pid=xxx`,用 `run.bat` 的 **选项 4** 杀掉残留进程, 它会先按 `widget_pid.txt` 里记录的 pid 杀,再用 PowerShell 扫所有命令行带 `widget_main.py` 的进程兜底。手动做的话:任务管理器里找 `pythonw.exe` 结束,然后删掉 `widget_pid.txt`。 - **改完代码后,桌面那个小组件还是旧的**:这是正常的。已经跑着的实例不会热加载 新代码,而且它还占着 `widget_pid.txt` 的锁,所以你重新双击启动时新进程会立刻退出 (日志最后一行是 `another instance is already running pid=xxx`),cmd 窗口关了, 桌面上的窗口却是那个旧实例——看着像「又打不开了」。用 `run.bat` 的 **选项 5**: 它杀掉残留实例、清锁、直接拉起新实例,一步搞定。只想要中间那步的话用 **选项 4**。 - **提示 No Python found**:跑 `setup.ps1`,或自己装好 Python 后再双击 `run.bat`。 - **提示 Installing the packages failed**:网络问题。手动执行 `pip install pyqt5 pymysql`,pypi 慢的话用 `pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pyqt5 pymysql`。 - **改完代码/改完依赖后仍报旧错**:删掉根目录的 `todo_widget_error.log` 再启动, 避免看到上一轮的日志。 - **窗口还能打开,但点按钮没反应 / 偶尔闪退**:直接看运行期日志, `notepad todo_widget_debug.log`。每次点击、编辑、删除、拖拽、保存都有一行记录, 日志**最后一条**就是出问题的动作;如果它之后什么都没有,说明进程在那个动作上直接崩了 (真正的段错误 Python 拦不住,只能靠日志停在哪一行为判断线索)。 ## 日志 程序会在小组件目录下写两个日志文件: | 文件 | 内容 | 说明 | | --- | --- | --- | | `todo_widget_debug.log` | 运行期日志:启动信息、数据库后端、**每次点击/编辑/删除/拖拽/保存**、每次列表刷新、所有未捕获异常 | 追加写,每行立刻 flush(进程被杀也能看到最后一条);超过 512KB 自动轮转为 `todo_widget_debug.log.old` | | `todo_widget_error.log` | 启动即崩时的完整 traceback + 依赖修复提示 | 只有启动失败才会重写;`run.bat` 会直接 `type` 出来 | 排查「点了没反应」的顺序: 1. `notepad todo_widget_debug.log` 2. 找到你点按钮那条 `click [+ new task] tid=...` 3. 看它后面有没有 `refresh[add_root] rows=... meta=...` 和 `new task ... is visible` 4. 有 `refresh` 但没有 `new task ... is visible`,会出现一行 `WARNING ... 新建任务没有出现在列表里`,说明数据写进去了但没渲染出来 5. `WARNING` 都看不到 → 进程在 `refresh` 里崩了,日志停在上一条就是现场 日志里所有带 `WARN` / `ERROR` / `FATAL` 的行都是值得看的;`INFO` 行是普通操作流水。 > 注意:`run.bat` 和 `setup.ps1` 是**故意只写英文**的。cmd.exe 按系统 ANSI 代码页 > (中文 Windows 是 GBK)逐字节解析 `.bat`,PowerShell 5.1 也会把无 BOM 的 `.ps1` > 当 ANSI 读;一旦脚本里出现中文或 `chcp 65001`,后面的行就会被解成乱码并被当成 > 命令执行(表现为 `'xxx' 不是内部或外部命令`)。这两个文件请勿添加中文。 ## MySQL 配置 编辑 `config.json`(或在设置面板里填): ```json { "mysql_host": "127.0.0.1", "mysql_port": 3306, "mysql_user": "root", "mysql_password": "你的密码", "mysql_database": "todo_widget", "mysql_timeout": 8 } ``` 程序会自动建库建表,不需要手动写 SQL。第一次连上时会把本地 JSON 里的任务同步进 MySQL。 连不上 MySQL 不影响使用,会自动用本地 `todo_desktop_widget_store.json` 存数据,界面左下角显示黄色圆点提示。 ## 功能说明 ### 任务操作 - 点顶栏 `+` 按钮添加一级任务 - 右键任务行(或点 `⋮`)弹出操作菜单:完成/撤销完成、添加子项、隐藏/显示、删除 - 双击任务文字 → 行内编辑,回车保存,`Esc` 取消;清空内容保存 = 删除该任务 - 点左侧 `▶`/`▲` → 展开/收起子项(iconfont 图标,有子项时才显示) - 按住任务行拖动 → 排序(拖到目标行上半部分插前面,下半部分插后面,拖动时显示蓝色指示线;也能把任务拖到别的父任务下) - 编号自动:一级 1, 2, 3…;子项 1.1, 1.2…;隐藏和折叠不影响编号连续性 - 编辑时输入框只显示原始内容,不含编号,避免保存后编号重复 ### 分栏布局 - 待办区 / 已办区用 QSplitter 分隔,可拖拽调整两区高度比例 - 已办区可折叠:点击底部「已办 ▶/▲」标签展开或收起,状态自动保存 - 已办任务按完成时间倒序排列(最近完成的在最上面) - 已办父任务的子项跟随父级显示在已办区,不会出现在待办区 - 无已办任务时自动折叠已办区 ### 顶栏图标按钮 | 图标 | 功能 | | --- | --- | | ✓ | 全部完成(将当前所有未完成任务标记完成) | | ↑ | 窗口置顶开关 | | ⚙ | 打开设置面板 | | 👁 | 显示/隐藏已隐藏任务 | | + | 新建任务 | | × | 关闭窗口(最小化到系统托盘) | ### 窗口 - 按住顶部栏拖动 → 移动位置 - 按住四边/四角 → 调整大小(有最小尺寸限制 260×190) - 位置和大小自动保存,下次启动恢复 - 高 DPI 屏幕自动缩放 ### 外观(设置面板 ) - 背景色 / 文字色 / 强调色 / 完成态颜色 / 隐藏态颜色(点击色块弹出取色器) - 字号 11–22px(滑块调节) - 透明度 50%–100% - 窗口高度 300–2000px - 窗口置顶 / 显示隐藏项(复选框) ### 数据 - 设置面板里 `导出备份` / `导入备份`(JSON 格式,可换电脑迁移) - MySQL 连接参数可在设置面板中配置并测试连接 ### 系统托盘 - 关闭窗口后最小化到系统托盘,双击托盘图标恢复窗口 - 右键托盘图标:显示窗口 / 设置 / 退出 ## 目录结构 ``` todo-widget/ ├── run.bat 一键启动(菜单:1 正常 / 2 后台 / 3 开日志 / 4 杀残留进程 / 5 杀掉并重启;只含英文) ├── 后台启动.vbs 无控制台窗口启动(用 pythonw.exe) ├── 开机自启.vbs 一键开关开机自启(在「启动」文件夹放/删快捷方式) ├── setup.ps1 一键安装(含便携版 Python 下载,只含英文) ├── requirements.txt 依赖清单(pyqt5>=5.15.9, pymysql>=1.0) ├── config.json MySQL 连接配置 ├── config.example.json 配置示例 ├── python_path.txt run.bat 记录的可用 Python 解释器(后台启动.vbs 靠它找 pythonw) ├── widget_pid.txt 单实例锁:当前实例的进程号(自动创建/删除) ├── todo_widget_error.log 启动失败时的报错(自动创建) ├── todo_widget_debug.log 运行期日志(自动创建,512KB 后轮转为 .old) ├── todo_desktop_widget_store.json 本地 JSON 存储(自动创建) ├── todo_desktop_widget_settings.json 外观/窗口配置(自动创建) ├── icon/ iconfont 图标字体(统一图标风格) │ ├── iconfont.ttf 字体文件 │ ├── iconfont.json 图标映射表 │ └── ... ├── python/ 便携版 Python(setup.ps1 生成,可整个删除) └── widgets/ ├── widget_main.py 主窗口(无边框/透明/拖拽/缩放/分栏/系统托盘) ├── task_item.py 任务行(勾选/折叠/编辑/拖拽排序/右键菜单) ├── settings_panel.py 设置面板(配色/字号/透明度/MySQL/备份) ├── widget_css.py 全局配色与样式表 ├── db.py 数据层(MySQL 5.7 + JSON 回退,自动建库建表) └── logger.py 日志模块(写上面两个日志文件 + 全局异常钩子) ``` ## 常见问题 **Q: 打开黑框一闪就没了?** A: 双击 `run.bat`(不要右键"运行"后立刻关掉窗口),它会打印 `todo_widget_error.log` 里的报错。最常见原因是缺依赖:先跑 `setup.ps1`,或手动 `pip install pyqt5 pymysql`。 **Q: 左下角显示"本地存储"?** A: MySQL 没连上。检查 `config.json` 的主机/端口/用户名/密码,或确认 MySQL 服务在运行。不连 MySQL 也能正常用,只是数据存在本地文件。 **Q: 想开机自动启动?** A: 双击 `开机自启.vbs` 即可,再双击一次就取消。 它是在「启动」文件夹里放/删快捷方式,不写注册表。 想手动做的话:`Win+R` → `shell:startup` → 把 `后台启动.vbs` 拖进去。 注意别拖 `run.bat`,那样开机会有个黑窗口。 **Q: 高 DPI 屏幕下窗口位置/大小异常?** A: 程序已启用高 DPI 缩放。如果仍有问题,右键 `run.bat` → 属性 → 兼容性 → 更改高 DPI 设置 → 覆盖高 DPI 缩放行为 → 应用程序。 **Q: 点了「+ 新任务」没反应,或者窗口闪退?** A: 先开 `todo_widget_debug.log`(在小组件目录下)。找到那条 `click [+ new task] tid=...`,看后面发生了什么: - 有 `refresh[add_root] ...` 但没有 `new task ... is visible` → 会出现 `WARNING ... 新建任务没有出现在列表里`,说明数据已入库但没渲染出来; - 什么 `refresh` 都没有 → 进程崩在那个动作上。日志停在最后一条就是崩溃现场。 另外窗口是 `Qt.Tool` 无边框窗口,点击后如果焦点被别的窗口抢走,新任务行会正常插入但 编辑框抢不到焦点——先点一下小组件窗口本身,再看输入框是否出现。 ## 技术栈 - **Python 3.8+**(推荐 3.11,便携版自动下载) - **PyQt5 >= 5.15.9**(UI 框架,支持 Python 3.12+) - **PyMySQL >= 1.0**(MySQL 驱动) - **iconfont**(统一图标风格,通过 QFontDatabase 加载 TTF 字体) ## License MIT![输入图片说明](Snipaste_2026-09-20_09-26-29.png)