Featured image of post WordCard技术文档

WordCard技术文档

程序WordCard的安装和函数功能说明文档

WordCard 技术文档

版本:1.0


简介

WordClock 是基于 customtkinter 的桌面小工具,用于在桌面悬浮窗中循环显示单词及其翻译,并支持从 JSON 导入词表、将词表写入 SQLite 数据库、通过系统托盘控制程序、保存窗口位置及设置等功能。

主要特点:

  • 悬浮、圆角、透明窗口,常驻桌面并支持拖动和隐藏到托盘。
  • 自动按间隔随机切换单词并更新 UI。
  • 支持将 JSON 词表导入到 SQLite 并作为可选词表使用。
  • 支持通过设置窗口管理词表、设置切换间隔、删除词表与制作 JSON 文件。
  • 使用多线程处理长耗时操作(导入、加载词表、托盘)以保证 UI 不阻塞。

快速开始

  1. 安装依赖(示例):
1
pip install customtkinter pystray pillow

注意:customtkinter 依赖 tkinter(通常随 Python 自带),若缺少请安装对应系统包。

  1. 将代码保存为 word_clock.py,并确保同目录下有 单词.db(或指定其他路径)。
  2. 运行:
1
python word_clock.py
  1. 第一次运行会生成 settings.json(默认 intervaltime = 5 秒),可在设置窗口调整。

环境依赖

  • Python 3.8+
  • tkinter(GUI)
  • customtkinter
  • pystray
  • pillow (PIL)
  • sqlite3(Python 标准库)

平台注意:代码中使用了 Windows 特定的 Win32 API(通过 ctypes)来隐藏任务栏图标,因此最佳运行环境为 Windows。在非 Windows 系统上应移除或条件兼容该部分。

文件结构

假设单文件项目:

1
2
3
wordcard.py
单词.db          # SQLite 数据库(可选,程序会尝试连接)
settings.json    # 程序运行后生成或更新

导入的 JSON 文件示例(每个元素为对象):

1
2
3
4
[
  {"word": "apple", "translate": "苹果"},
  {"word": "book", "translate": "书"}
]

主要类与方法说明

WordClock (继承自 ctk.CTk)

描述:应用的主窗口类,封装 UI、数据库连接、托盘、线程与设置保存。

属性(重要)

  • SETTINGS_FILE:字符串,默认 settings.json
  • db_path:SQLite 数据库路径,默认 单词.db
  • db_conn, db_cursor:数据库连接与游标(持久连接,check_same_thread=False)。
  • wordtables:从 SQLite 读取到的表名列表。
  • words_list:当前选中词表对应的单词列表,元素为 (word, translate)
  • intervaltime:单词切换时间间隔(秒)。
  • running:布尔,控制自动更新线程运行。
  • loading:布尔,指示是否处于词表加载中,用于暂停自动刷新。

方法摘要(按功能分组)

  • 初始化与窗口配置
    • __init__(self, db_path="单词.db"):创建窗口、加载配置、打开数据库连接、启动托盘线程与自动刷新线程、绑定关闭事件等。
    • hide_from_taskbar(self):使用 ctypes 调用 Win32 API 将窗口从任务栏隐藏(Windows-specific)。
    • bind_drag_events(self)start_dragon_drag:支持拖动并在拖动时保存位置。
  • 设置存取
    • load_settings(self):读取 settings.json,若不存在返回默认配置。
    • save_settings(self):保存窗口位置、当前选表名、间隔等到 settings.json
    • on_close(self):窗口关闭回调,保存设置并退出。
  • 数据库与数据加载
    • fetch_wordtables(self, db_path):读取 SQLite 中的表名并存入 self.wordtables。SQL 为 SELECT name FROM sqlite_master WHERE type='table' ORDER BY rowid;
    • load_words_from_db(self, db_path, table_name=None):读取指定表的 word, translate 列并返回列表;若未传表名,默认取 self.wordtables[0]
    • json2sqldb(self, file_address, file_name):将 JSON 数据写入新建的 SQLite 表,包含事务优化(调整 PRAGMA、BEGIN TRANSACTION、executemany、commit),最后恢复 PRAGMA 设置。
  • 自动切换与UI更新
    • auto_update_words(self):后台线程循环,根据 self.intervaltime 随机选择单词并通过 after(0, ...) 回到主线程更新 UI。会在 self.loading=True 时短暂等待以避免冲突。
    • display_translation(self, text):当翻译过长时设置 wraplength 以换行显示。
  • 托盘相关
    • setup_tray(self):构造托盘图标与菜单(显示/隐藏、设置、退出),并运行事件循环(pystray)。独立线程运行。
    • toggle_window(self, icon=None, item=None):切换窗口显示/隐藏。
    • quit_app(self, icon=None, item=None):停止线程、关闭数据库并退出。
  • 设置窗口与词表管理
    • so_setting(self):打开设置窗口,构建左侧控制按钮与右侧显示词表的滚动区域,并异步加载表名。
    • load_wordtables_async(self):后台加载表并回调 put_tables_on_right
    • put_tables_on_right(self):基于 self.wordtables 在滚动区构建按钮并支持高亮当前表。
    • on_label_click_with_confirmation(self, name, button):点击某个词表按钮弹出确认框,确认后显示遮罩并在后台加载数据,加载完成后更新 UI 与当前表。
    • del_wordtable(self) / confirm_delete(self, table_name, popup):删除选中表并刷新 UI。
    • open_make_wordtable_window(self) / generate_json_from_text(self, text_box, win):允许用户粘贴文本快速生成 JSON 文件(每行 单词 翻译),并保存 JSON。
  • 加载遮罩与动画
    • _create_loading_overlay(self, message="正在加载…"):在 main_frame 上创建覆盖层(遮罩)并返回 overlay。
    • _start_loading_animation(self, overlay):使用 after 循环更新点点动画,直至 self.loading=False
    • _stop_loading_animation(self):取消动画任务。
  • 辅助弹窗
    • show_popup(self, message: str, duration: int = 1800):自定义 CTkToplevel 弹窗,代替未加载的 CTkMessagebox

数据库与数据格式

  • SQLite 表结构(在 json2sqldb 创建)
1
2
3
4
5
CREATE TABLE <table_name> (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  word varchar(255) NULL DEFAULT NULL,
  translate TEXT NULL
);
  • JSON 导入格式:数组,每项为对象:{"word": "xxx", "translate": "yyy"}
  • 注意:代码假设表中存在 wordtranslate 字段。若你的原始表结构不同,需修改 load_words_from_db 查询语句。

设置与持久化(settings.json)

settings.json 存储字段:

  • pos_xpos_y:上次窗口位置(像素坐标)。
  • last_table:上次使用的词表名。
  • intervaltime:单词自动切换间隔(秒)。

默认文件会在程序首次运行时创建(intervaltime=5)。保存由 save_settings() 完成(拖动、修改间隔、关闭时等触发)。

运行与调试建议

  • 数据库无法连接:确认 db_path 路径正确且文件存在。若数据库为空,程序的 fetch_wordtables 可能返回空列表,load_words_from_db 会返回占位 ("No word","无")
  • 线程安全:使用了 sqlite3.connect(..., check_same_thread=False) 来允许多线程访问。但推荐仅主线程使用游标并在子线程使用新的连接(sqlite3.connect(self.db_path))以避免潜在竞态。
  • 托盘图标不显示或程序无反应pystray 在某些平台或环境需要额外配置。测试时可先注释 setup_tray 并直接运行主窗口检查 UI。
  • 隐藏任务栏仅在 Windows 生效hide_from_taskbar() 使用 Win32 API,仅在 Windows 上有效,跨平台请条件判断或移除。
  • 日志与异常:建议扩展 printlogging 模块,并在关键异常中记录堆栈信息以便排查。

常见问题与解决方法

  • 问:窗口没有显示单词或只显示 No word
    • 因为数据库中没有表或表中没有数据。确保通过导入 JSON 创建了至少一个表或手动向 SQLite 中插入数据。
  • 问:点击词表按钮没反应。
    • 检查 word_table_buttons 是否正确生成,以及 self.wordtables 是否有数据。
  • 问:应用未隐藏到系统托盘或无法退出。
    • 检查 pystray 是否正常安装并且在当前平台支持托盘操作。临时方法:直接关闭窗口或在代码中调用 quit_app()

扩展与改进建议

  • 使用线程池/Executor:替换原始 threading.Threadconcurrent.futures.ThreadPoolExecutor 以更好地管理线程生命周期与异常捕获。
  • 数据库连接策略:将长期持久连接改为“按线程新建连接”的策略(每个线程独立连接),以避免跨线程共享同一游标导致的问题。
  • UI 优化:为长文本增加动效、增加单词发音(调用 TTS 或在线 API)、支持多语言界面切换。
  • 配置界面改进:在设置窗口直接显示并编辑 intervaltime,支持导入 CSV、 Excel;提供词表导出功能(JSON / CSV)。
  • 跨平台兼容:为 hide_from_taskbar 添加平台判断,并实现 macOS / Linux 下替代实现或跳过该功能。
  • 错误日志:集成日志文件输出以及可选的错误上报(不建议在个人项目中默认开启)。

附:典型 JSON 输入示例

1
2
3
4
5
[
  {"word": "apple", "translate": "苹果"},
  {"word": "book", "translate": "书"},
  {"word": "computer", "translate": "电脑 计算机"}
]
恍如昨日,嗤笑今朝
使用 Hugo 构建
主题 StackJimmy 设计