Releases: Kiuyor/Check-number
Release list
v9.4 — 崩溃修复与窗口自适应
v9.4 — 崩溃修复与窗口自适应
🐛 修复
- P0-1: 修复多人抽取连续执行时的 ValueError(概率缓存未随候选池变化失效,
导致抽到已从 remaining 移除的学生) - P0-1: 修复快速连续抽取时的 QGraphicsOpacityEffect 悬空指针崩溃
(旧动画未 stop、旧 Effect 未清除就被新 setGraphicsEffect 隐式删除)
🔧 代码改进
- 新增动态窗口自适应:QFontMetrics 实测文本宽度 48→16px 迭代降字号,
窗口自动扩展至 600px 宽,极端长名启用 WordWrap 换行增高 - 新增 resizeEvent 重写 + _reset_window_for_draw 方法,窗口缩放时
shadow 圆角背景和悬浮按钮自动跟随 - perform_multi_draw 每轮循环前失效概率缓存,确保用最新候选池重算
下载: CheckNumber-Setup.exe (27.2 MB)
v9.3 — 算法公平性升级与多人抽取
v9.3 (2026-06-14) — 算法公平性升级与多人抽取
🎯 新功能
- 多人抽取:右键菜单 → 多人抽取...(Ctrl+M),滑块选择 2–10 人,无放回抽取
- 连续不重复保护:同一学生不会连续两轮被抽中(除非只剩 1 人)
- 概率可视化:统计弹窗新增"当前概率"列;新增"查看概率分布"水平条形图面板
- 多人结果适配:字体按文本长度自适应缩小
- 动态窗口自适应:QFontMetrics 精确测宽,48→16px 迭代降字号
- 窗口宽度自动扩展至 600px,极端长名启用 WordWrap 换行增高
- 每次单人抽取后窗口自动恢复默认 280×140
⚖️ 算法升级 — 三层公平性保护
- 平均值过滤:当最大-最小抽取次数差距 > GAP_THRESHOLD(3) 时,
排除 count > 平均值的候选者,仅允许低频学生进入候选池 - 候选池下限保障:候选池不低于总人数的 CANDIDATE_POOL_MIN_RATIO(30%),
自动补回 count 最低的被排除者 - 冷启动参数:COLD_START_FLOOR_RATIO(0.5) 留作未来扩展
🔧 代码改进
- StatsManager 新增 get_probability()、increment_and_update_cache()、
increment_batch_and_update_cache() 方法 - Config 新增 GAP_THRESHOLD / CANDIDATE_POOL_MIN_RATIO / COLD_START_FLOOR_RATIO 常量
- 新增 WINDOW_MAX_WIDTH(600) / WINDOW_MIN_SIZE / WINDOW_H_PAD 常量
- perform_draw / perform_multi_draw 使用缓存预热方法替代旧 invalidate 模式
- main_window.py 新增 _show_multi_draw_dialog()、_show_probability_panel()
- 新增 _reset_window_for_draw()、resizeEvent 重写,窗口缩放自动跟随
- animate_result 用 QFontMetrics 动态字号取代四级阶梯
🐛 崩溃修复
- P0-1: animate_result 先 stop 旧动画 + setGraphicsEffect(None) 清除旧 Effect
再创建新 Effect,消除快速连续抽取时的悬空指针崩溃 - perform_multi_draw 开头加 self._flash = None,防止闪动状态残留
- _show_multi_draw_dialog 加 _flash 非空守卫,动画中重复触发被忽略
🧪 测试
- tests/test_core.py 新增 8 个测试用例(共 21 个)
- 覆盖:平均值过滤触发、候选池下限、小差距不过滤、get_probability、
增量缓存更新、批量缓存更新、空名单、单人名单
v9.2 — 代码坏味道重构
v9.2 (2026-06-08) — 代码坏味道重构
🧹 代码清理(18 项修复,P0~P3)
P0 安全/可靠性:
- ensure_initialized 新增 invalidate_cache() 调用,修复名单变更后概率缓存未失效的 bug
- Config.write_json 改为 tmp+replace+fsync 原子写入模式,避免写入中断残损文件
P1 架构/设计:
- 新增 StatisticsManager.increment() 封装抽取计数,消除 perform_draw 对 stats 字典的直接操作
- 提取 StudentManager._encrypt_write() 静态方法,消除 _save_names_to_enc/import_student_list 中的加密写入重复
- 提取 _build_checkable_menu() 子菜单工厂,contextMenuEvent 从 90→55 行
- 消除 self.sound_enabled 影子变量,统一使用 Config.sound_enabled
P2 可维护性:
- 新增 tests/test_core.py,含 13 个单元测试覆盖 XOR 加解密、色彩工具、概率计算、缓存管理、JSON 持久化
- design_tokens 数据驱动重构:7 套方案从 77 行重复 dict 压缩为 7 行元组 + 自动派生
- prepare_students_file 拆分为 _upgrade_plaintext / _load_or_generate 三步
- float_ball 魔法数字 5 提取为 _CLICK_THRESHOLD 类常量
- _setup_dpi 移除 ~25 行 Qt <5.14 兼容代码
P3 代码清理:
- splash_screen 魔法尺寸提取为类常量,移除未使用 QFont 导入
- Config 类变量文档加固
📦 分发
- 入口文件更新为 v9.2.py
- Nuitka standalone + NSIS 安装包构建
- GitHub Release v9.2 发布
v9.1 — 功能增强与架构精炼
Check-number 更新日志
v9.1 (2026-05-31) — 功能增强与架构精炼
🎯 新功能
- 窗口透明度自定义:右键菜单 → 窗口透明度,5 档预设(30%~90%)+ 滑块实时预览
- 显示字体切换:右键菜单 → 显示字体,4 款字体可选(HarmonyOS Sans / Inter Display / Open Sans / Noto Sans)
- 默认字体从 Microsoft YaHei 切换为 HarmonyOS Sans(鸿蒙字体)
🧹 代码质量(第二轮审查,17 项修复)
P0 安全/可靠性:
- Config.load_preferences 对 window_opacity 增加 0.25–1.00 钳位,font_family 白名单校验
- Config.set_window_opacity / set_font_family 新增 save 参数,实时预览不写磁盘
- 4 处裸 except Exception 窄化为具体异常类型(OSError / UnicodeDecodeError / ImportError)
P1 架构/设计:
- RandomSelectorWindow 1094 行拆分为 4 个类(核心重构):
· StudentManager(student_manager.py, 165 行)— 名单加载/导入/加解密
· StatisticsManager(stats_manager.py, 113 行)— 统计 CRUD/概率计算/导出
· HistoryManager(history_manager.py, 96 行)— 历史记录 CRUD
· RandomSelectorWindow(main_window.py, 869 行)— UI + 事件 + 协调整合 - _build_table_dialog 新增 extra_buttons 参数,消除历史对话框的布局 hack
P2 可维护性:
- design_tokens 移除 7 套方案中未使用的 shadow_color 死代码(含 QColor 导入)
- FloatBall.init 声明 _press_origin 属性
- 透明度预设菜单去除 "默认" 前导空格
- FlashAnimation.start() 冻结学生名单快照,防止外部修改导致崩溃
P3 代码清理:
- main_window.py 删除未使用的 import io / json / datetime / QFileDialog / QFont / QColor
- sound_manager.py 音效频率/时长提取为类常量(NOTE_A4 / TICK_MS / NOTE_MS 等)
- v8.0.py 高 DPI 兼容块裸 except 窄化
📦 分发
- Nuitka standalone 编译:CheckNumber.exe (7.4 MB),含 whs_update 数据文件
- NSIS 安装包:CheckNumber-Setup.exe (19.8 MB),注册卸载程序 + 开始菜单/桌面快捷方式
- GitHub Release v9.0 发布,含完整中文更新日志
- 安装程序版本号从 v8.2 更新至 v9.0
📂 模块结构(12 个文件)
v8.0.py — 应用入口
config.py — 配置、路径、偏好、QSS
design_tokens.py — 6 套配色方案 Token
main_window.py — 主窗口(UI + 事件 + 对话框)
student_manager.py — 名单管理
stats_manager.py — 统计管理
history_manager.py — 历史管理
float_ball.py — 可拖拽悬浮球
splash_screen.py — 启动画面
flash_animation.py — 名字闪动动画
sound_manager.py — winsound 音效
students_example.txt — 示例名单
v9.0 (2026-05-31) — 模块化重构与代码质量
🎯 新功能
- 名单导入:右键菜单 → 导入名单,支持选择 .txt 文件替换当前名单
- 名单持久化:导入的名单加密存储,关闭应用后不重置
- 示例名单:随附 students_example.txt(40 个姓名)
🧹 代码质量(31 项修复,P0~P3)
P0 安全/可靠性:
- 加密密钥优先从环境变量 CHECK_NUMBER_KEY 读取
- 文件 I/O 异常不再静默吞掉,损坏文件自动备份为 .corrupted
- 名单解密完全在内存中完成,不再写明文临时文件
- 名单加密使用原子写入(os.replace),防止写入中断损坏
- winsound 导入提升至模块级别,消除热路径重复 import
P1 架构/设计:
- FloatBall 提取至独立模块 float_ball.py
- Config 新增 set_color_scheme/set_sound_enabled/set_window_position 类方法
- JSON 读写从 4 个重复方法合并为通用 _read_json/_write_json
- 统计/历史对话框从 ~140 行重复代码提取为 _build_table_dialog 工厂
- xor_encrypt_decrypt 改为 @staticmethod
- showMinimized 重命名 minimize_to_float
- SplashScreen 淡出信号改为显式链式调用
P2 可维护性:
- 全代码库添加类型标注
- 统一使用 os.path.join 构建路径
- 新增 Config.get_font() 统一字体工厂
- UI 布局常量提取至 Config(MIN_BTN_POS、DIALOG_BTN_SIZE 等)
- 硬编码颜色统一通过 DesignTokens 路由
- _hex_to_rgb 增加输入校验
- sRGB→线性转换代码提取为 _srgb_to_linear 复用
- DesignTokens._COMMON → _DEFAULTS + 覆盖机制文档
- QSS 样式表从 140 行巨石拆分为 9 个组件方法
P3 代码清理:
- 移除未使用的 create_example_students/use_example_students
- 移除冗余 _shadows_deferred 标志
- SplashScreen 点动画帧提升为类常量
- 弃用 DPI 属性增加 Qt 版本守卫
🖱️ 右键菜单重组
- 移除:最小化窗口、关闭窗口、设置子菜单(含音效/快速模式)
- "导入名单" → 顶级菜单项
- "重置统计" → "重置数据"
- "配色方案" → 顶级子菜单
- "快捷键说明" 移至关于软件前
- 新增:关闭程序
🐛 修复
- FloatBall 移除 QGraphicsDropShadowEffect,修复 UpdateLayeredWindowIndirect 错误
📦 模块结构(9 个文件)
v9.0.py — 应用入口
config.py — 配置、路径、偏好、QSS
design_tokens.py — 6 套配色方案 Token
main_window.py — 主窗口
float_ball.py — 可拖拽悬浮球
splash_screen.py — 启动画面
flash_animation.py — 名字闪动动画
sound_manager.py — winsound 音效
students_example.txt — 示例名单
v8.0 (2025) — PyQt5 完整重写
- 从 tkinter 迁移至 PyQt5,单文件 ~577 行
- 无边框半透明窗口、启动画面、悬浮球最小化
- 逆频次加权概率算法
- QThread 动画线程 + QGraphicsOpacityEffect 淡入效果
- 统计数据管理 + HTML 表格弹窗
- XOR 名单加密
v5.0.0 (2024) — tkinter 成熟版
- 三种变体:基础版 / PPT 定制版 / PyQt5 实验版
- tkinter GUI 完善
- 基本数据统计与导出
v4.5.0 (2024) — UI 优化
- 界面美化
- 功能稳定
v4.0.0 (2023) — 功能扩展
- 新增统计分析
- 数据持久化
v3.0.0 (2023) — 首个正式版
- tkinter 基础 GUI
- 随机点名核心功能
v2.0.0 (2023) — 原型
- tkinter 简单窗口
- 基础随机抽取
v9.0 — 模块化重构与代码质量全面优化
Check-number v9.0 正式发布 🎉
🎯 新功能
- 名单导入:右键菜单 → 导入名单,选择 .txt 文件替换当前名单
- 名单持久化:导入的名单加密存储,关闭应用后不重置
- 示例名单:随附 students_example.txt(40 个姓名)
🧹 代码质量(31 项修复)
P0 安全 / 可靠性
- 加密密钥优先从环境变量
CHECK_NUMBER_KEY读取 - 文件 I/O 异常区分处理(FileNotFoundError / JSONDecodeError / OSError)
- 损坏文件自动备份为
.corrupted - 名单解密完全在内存中完成,不再写明文临时文件
- 名单加密使用原子写入(
os.replace),防止写入中断损坏 winsound导入提升至模块级别,消除热路径重复 import
P1 架构 / 设计
- FloatBall 提取至独立模块
float_ball.py - Config 新增
set_color_scheme/set_sound_enabled/set_window_position类方法 - JSON 读写从 4 个重复方法合并为通用
_read_json/_write_json - 统计/历史对话框从 ~140 行重复代码提取为
_build_table_dialog工厂 xor_encrypt_decrypt改为@staticmethodshowMinimized重命名为minimize_to_float(保留旧方法向后兼容)- SplashScreen 淡出信号改为显式链式调用
P2 可维护性
- 全代码库添加类型标注
- 统一使用
os.path.join构建路径 - 新增
Config.get_font()统一字体工厂 - UI 布局常量提取至 Config(
MIN_BTN_POS、DIALOG_BTN_SIZE等) - 硬编码颜色统一通过 DesignTokens 路由
_hex_to_rgb增加输入校验- sRGB→线性色彩空间转换提取为
_srgb_to_linear复用 - DesignTokens
_COMMON→_DEFAULTS+ 三层合并策略文档 - QSS 样式表从 140 行巨石拆分为 10 个组件方法
P3 代码清理
- 移除未使用的
create_example_students/use_example_students - 移除冗余
_shadows_deferred标志 - SplashScreen 点动画帧提升为类常量
_DOT_FRAMES - 弃用 DPI 属性增加 Qt 版本守卫
🖱️ 右键菜单重组
├── 导入名单
├── ──────────────
├── 统计 ▸ (查看统计信息 / 查看抽取历史 / 清除抽取历史 / ─ / 重置数据 / 导出统计数据)
├── 配色方案 ▸ (靛蓝 / 海蓝 / 翡翠绿 / 日落橙 / 玫瑰粉 / 紫罗兰 / 晴空蓝)
├── ──────────────
├── 快捷键说明
├── 关于软件
├── ──────────────
├── 关闭程序
🐛 修复
- FloatBall 移除
QGraphicsDropShadowEffect,修复UpdateLayeredWindowIndirect错误 whs_update路径在 Nuitka 编译后自动解析到 exe 所在目录
📦 模块结构(9 个文件)
v9.0/
├── v9.0.py # 应用入口
├── config.py # 配置、路径、偏好、QSS 样式
├── design_tokens.py # 6 套配色方案 Token
├── main_window.py # 主窗口(UI + 业务逻辑)
├── float_ball.py # 可拖拽圆形悬浮球
├── splash_screen.py # 启动画面
├── flash_animation.py # 名字闪动动画
├── sound_manager.py # winsound 音效
└── students_example.txt # 示例名单(40 人)
📥 安装
下载 CheckNumber-Setup.exe 运行即可。支持 Windows 10/11。