Tkinter i18n (中文即 key)
A lightweight, gettext-free i18n scheme for Tkinter apps. Chinese strings are the
dictionary keys; an _EN table holds English; unknown keys fall back to the
Chinese source so the UI never shows blank/missing text.
When to use
- A user wants a Tkinter tool bilingual (中文 / English) or multi-language.
- Need auto-detect of system language + a manual dropdown + "remember my choice".
- Avoid gettext (it does not survive PyInstaller
--onefilefreezing cleanly).
Pattern
- Define
t(key, *args)— returns_EN.get(key, key), thenstr % argsif
args present. Never raises on missing keys. - Keep one
_EN = {...}table. Add an entry for every user-visible string. _detect_lang()— Windows:ctypes.windll.kernel32.GetUserDefaultUILanguage()
& 0xFF == 0x04→ Chinese, else English. Fallback tolocaleon non-Windows.- Persist choice to
~/.workbuddy/APP.lang(zh/en); load at startup. - Manual switch: write the file, then restart the process
(os.execv(sys.executable, [sys.executable] + sys.argv)) so every widget
rebuilds with the new language. Per-widget live redraw is fragile — restart
is simpler and reliable.
See references/i18n_template.py for a complete, runnable minimal app.
Wiring checklist
- [ ] Import
tat top; wrap every user-visible string (titles, buttons,
labels, messageboxes, status text, model display names, dropdown labels). - [ ] Add a language
ttk.Combobox(top-right) bound to the switch handler. - [ ]
LANG_ORDER = ["zh", "en"],LANG_NAMES = {"zh": "中文", "en": "English"}. - [ ] Restart-on-change writes config then
os.execv. - [ ] Adding a language later = add a branch in
_detect_lang+ a new translation
table + extendLANG_ORDER/LANG_NAMES.
Notes
- Frozen (PyInstaller) safe: no external
.mofiles, nogettextruntime. - The language config path should live under
~/.workbuddy/so it is shared with
the agent's config dir, or under the app's own dir — pick one and be consistent.