* Add multi-language i18n support (English, Chinese, Japanese, Korean)
- Add i18n.py module for translation management via QTranslator
- Add Simplified Chinese (zh_CN), Japanese (ja_JP), and Korean (ko_KR) translations
- Integrate translation files into Qt resource system (KCC.qrc / KCC_rc.py)
- Add language switcher button in the top button bar of main window
- Language setting persists via QSettings
- Dynamic text updates work correctly after language switch
- Support %1, %2, %3 placeholders via tr_arg() helper function
- KCCGUI and KCCGUI_MetaEditor now inherit QObject for tr() support
* Complete Japanese/Korean/Chinese translations + fix language switch issues
- Fill 61 missing Japanese translations (tooltips, 3-state checkboxes, etc.)
- Fill 61 missing Korean translations (tooltips, 3-state checkboxes, etc.)
- Fill 6 missing Chinese translations
- Fix language menu: use QActionGroup for exclusive (single-select) checkmarks
- Fix jobList initial tips: refresh translations on language switch by
updating label text directly (preserves message order and user-added entries)
- Add PROJECT_I18N_README.md developer documentation
* Replace emoji language icon with PNG globe icon
Fixes PR review feedback from axu2: the emoji character doesn't render on Windows 7 (no emoji font support). Replaced with a PNG globe icon from Wikimedia Commons (CC license), loaded via Qt resource system for consistent cross-platform rendering.
* Fix RuntimeError when switching language: re-fetch labels from jobList
Previously, QLabel references were saved directly, but the underlying
C++ objects could be deleted by Qt, causing RuntimeError on access.
Now we save only source strings and re-fetch labels from jobList
items when updating, with try/except as a safety net.
* Use text label for language button instead of PNG icon
Replace the globe PNG icon with a plain text button (' 文 A ')
so its color automatically follows the system light/dark theme,
per review feedback. Removes icons/language.png and its QRC entry.
* Finalize i18n: retranslate jobList messages and translate CLI output
- Add source= to 16 GUI addMessage calls so already-shown messages retranslate on language switch
- Translate comic2ebook.py conversion/CLI messages via QCoreApplication.translate('KCCGUI', ...)
- Clear 29 unfinished WorkerThread translations (context unified to KCCGUI)
- Guard apply_language when QApplication is not yet created
- Trim dead imports and redundant code
* Avoid duplicated source strings: translate inside addMessage
Replace the self.tr/translate + source= pattern (same string written twice) with
QT_TRANSLATE_NOOP('KCCGUI', ...) at call sites; addMessage now translates internally
and stores the source text for retranslation on language switch.
- Drop the source parameter from addMessage; simplify signal to 3 args
- Include comic2ebook.py in lupdate (20 CLI/conversion messages)
* Add translation maintenance workflow
Add gen_translation_files.sh/.bat, TRANSLATION.md, and a README pointer; remove the superseded PROJECT_I18N_README.md.
* chmod +x
53 lines
1.6 KiB
Python
53 lines
1.6 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""KCC UI 语言切换辅助模块。"""
|
|
from PySide6.QtCore import QCoreApplication, QTranslator
|
|
|
|
# 语言代码 -> 菜单显示名(菜单按"各自语言"显示,不参与翻译)
|
|
LANGUAGES = {
|
|
'en': 'English',
|
|
'zh_CN': '中文(简体)',
|
|
'ja_JP': '日本語',
|
|
'ko_KR': '한국어',
|
|
}
|
|
DEFAULT_LANGUAGE = 'en'
|
|
|
|
# 模块级持有引用,防止 translator 被 GC 回收后失效
|
|
_translator = None
|
|
|
|
|
|
def apply_language(lang_code):
|
|
"""安装指定语言的 QTranslator,返回实际生效的 code。
|
|
|
|
语言文件打包在 qrc 资源 /i18n/ 前缀下。
|
|
"""
|
|
global _translator
|
|
app = QCoreApplication.instance()
|
|
if app is None:
|
|
# QApplication 尚未创建,无法安装翻译器;保持默认语言
|
|
return DEFAULT_LANGUAGE
|
|
if _translator is not None:
|
|
app.removeTranslator(_translator)
|
|
_translator = None
|
|
if lang_code not in LANGUAGES:
|
|
lang_code = DEFAULT_LANGUAGE
|
|
if lang_code != 'en':
|
|
t = QTranslator()
|
|
if t.load(f':/i18n/kcc_{lang_code}.qm'):
|
|
app.installTranslator(t)
|
|
_translator = t
|
|
else:
|
|
lang_code = DEFAULT_LANGUAGE
|
|
return lang_code
|
|
|
|
|
|
def tr_arg(translated_str, *args):
|
|
"""替换翻译字符串中的 %1, %2, %3 ... 占位符。
|
|
|
|
PySide6 的 tr() 返回 Python str 而非 QString,没有 .arg() 方法,
|
|
因此用此函数手动替换占位符。
|
|
"""
|
|
result = translated_str
|
|
for i, arg in enumerate(args, 1):
|
|
result = result.replace(f'%{i}', str(arg))
|
|
return result
|