在 PyQt6 中实现支持多种语言(国际化,简称 i18n)通常有两种方式:1. 可以通过使用 Qt 的 QTranslator
类来完成;2. 自定义字典来管理
1. 使用 Qt 的 QTranslator
类
1. 准备多语言资源文件
你需要创建一个翻译文件,以便将应用程序的文本翻译成不同的语言。
1.1 创建 .ts
文件
首先,你需要使用 Qt 的 lupdate
工具从 Python 代码中提取所有可翻译的字符串,并将它们存储到 .ts
文件中。
例如,你可以使用如下方法从 .py
文件中提取翻译内容:
lupdate your_app.py -ts translations/your_app_zh_CN.ts
这将生成一个包含所有可翻译文本的 .ts
文件。然后,你可以打开 .ts
文件并为每个文本项提供翻译。
1.2 编辑 .ts
文件
在 .ts
文件中,编辑 <translation>
元素以提供翻译。例如:
<context><name>MainWindow</name><message><source>Hello, World!</source><translation>你好,世界!</translation></message>
</context>
1.3 编译 .ts
文件为 .qm
文件
使用 lrelease
工具将 .ts
文件编译成 .qm
文件,这是运行时加载的翻译文件。
lrelease translations/your_app_zh_CN.ts
这将生成一个 your_app_zh_CN.qm
文件。
2. 在 PyQt6 应用中加载翻译文件
一旦你有了 .qm
文件,你就可以在 PyQt6 中加载它们并应用翻译。
2.1 导入相关模块
from PyQt6.QtCore import QCoreApplication, QTranslator, QLocale
from PyQt6.QtWidgets import QApplication, QMainWindow
2.2 设置翻译器
在应用程序的启动过程中,创建并加载翻译器。
class MyApp(QApplication):def __init__(self, argv):super().__init__(argv)# 创建翻译器self.translator = QTranslator()# 加载合适的语言翻译文件locale = QLocale.system().name() # 获取系统的当前语言translation_file = f"translations/your_app_{locale}.qm"if self.translator.load(translation_file):# 如果加载成功,安装翻译器self.installTranslator(self.translator)# 启动界面self.main_window = QMainWindow()self.main_window.show()app = MyApp([])
app.exec()
3. 使用 QObject.tr()
进行文本翻译
你需要将所有的可翻译文本包装在 QObject.tr()
方法中。这是让 Qt 能够识别并翻译字符串的关键步骤。
from PyQt6.QtWidgets import QLabel, QMainWindowclass MainWindow(QMainWindow):def __init__(self):super().__init__()label = QLabel(self)label.setText(self.tr("Hello, World!")) # 可翻译文本label.move(100, 100)label.resize(200, 50)self.setWindowTitle(self.tr("Main Window"))
在这个例子中,self.tr("Hello, World!")
会自动被翻译成当前语言。
4. 切换语言
你可以在程序中动态切换语言。为了支持语言切换,可以实现一个方法重新加载不同的 .qm
文件并更新界面。
def switch_language(self, language_code):# 创建新的翻译器translator = QTranslator()translation_file = f"translations/your_app_{language_code}.qm"if translator.load(translation_file):self.installTranslator(translator)# 更新界面文本self.retranslateUi()
在 retranslateUi()
方法中,你可以刷新界面上的所有文本,以便根据新语言重新加载。
5. 处理动态文本(例如按钮、菜单等)
除了 QLabel
之外,其他界面元素(如按钮、菜单等)也需要通过 tr()
方法进行翻译。
from PyQt6.QtWidgets import QPushButton, QVBoxLayout, QWidgetclass MainWindow(QMainWindow):def __init__(self):super().__init__()layout = QVBoxLayout()button = QPushButton(self.tr("Click me"))layout.addWidget(button)container = QWidget()container.setLayout(layout)self.setCentralWidget(container)self.setWindowTitle(self.tr("Main Window"))
6. 完整示例代码
from PyQt6.QtCore import QCoreApplication, QTranslator, QLocale
from PyQt6.QtWidgets import QApplication, QMainWindow, QLabel, QPushButton, QVBoxLayout, QWidgetclass MyApp(QApplication):def __init__(self, argv):super().__init__(argv)# 创建翻译器self.translator = QTranslator()# 加载合适的语言翻译文件locale = QLocale.system().name() # 获取系统的当前语言translation_file = f"translations/your_app_{locale}.qm"if self.translator.load(translation_file):# 如果加载成功,安装翻译器self.installTranslator(self.translator)# 创建主窗口self.main_window = MainWindow()self.main_window.show()class MainWindow(QMainWindow):def __init__(self):super().__init__()layout = QVBoxLayout()button = QPushButton(self.tr("Click me"))layout.addWidget(button)label = QLabel(self.tr("Hello, World!"))layout.addWidget(label)container = QWidget()container.setLayout(layout)self.setCentralWidget(container)self.setWindowTitle(self.tr("Main Window"))# 切换语言按钮switch_button = QPushButton(self.tr("Switch Language"))layout.addWidget(switch_button)switch_button.clicked.connect(self.switch_language)def switch_language(self):# 选择另一种语言,例如切换到中文language_code = "zh_CN" # 或者根据需要选择其他语言self.retranslateUi(language_code)def retranslateUi(self, language_code):# 重新加载语言文件并更新界面translator = QTranslator()translation_file = f"translations/your_app_{language_code}.qm"if translator.load(translation_file):self.installTranslator(translator)self.setWindowTitle(self.tr("Main Window"))self.centralWidget().children()[1].setText(self.tr("Hello, World!"))self.centralWidget().children()[2].setText(self.tr("Click me"))self.centralWidget().children()[3].setText(self.tr("Switch Language"))if __name__ == '__main__':app = MyApp([])app.exec()
总结
- QTranslator 用于加载翻译文件。
- 使用 tr() 方法包装所有要翻译的文本。
- 通过
lupdate
和lrelease
工具生成.ts
和.qm
文件,并在运行时加载它们。 - 可以动态切换语言,并刷新界面文本。
2. 自定义字典来管理
除了使用 Qt 提供的 QTranslator
和 .ts
文件来进行国际化,完全可以通过手动管理一个字典来实现多语言支持。这种方法适合简单的应用,尤其是在没有大量文本内容需要翻译的情况下。通过字典匹配不同的语言,你可以实现对 UI 元素的文本翻译。
如何用字典实现多语言支持
假设你想要支持两种语言:英语和中文,可以按以下步骤实现:
1. 创建语言字典
首先,你需要为每种语言定义一个字典,字典的键是文本的标识符,值是对应语言的翻译。
英文字典(en_dict
)
en_dict = {"greeting": "Hello, World!","click_button": "Click me","window_title": "Main Window","switch_language": "Switch Language",
}
中文字典(zh_dict
)
zh_dict = {"greeting": "你好,世界!","click_button": "点击我","window_title": "主窗口","switch_language": "切换语言",
}
2. 选择语言并使用字典
在程序中,你可以根据选择的语言切换字典的内容,并使用这些字典来设置 UI 元素的文本。
class MainWindow(QMainWindow):def __init__(self, language_dict):super().__init__()# 保存当前语言的字典self.language_dict = language_dictlayout = QVBoxLayout()# 使用字典翻译文本button = QPushButton(self.language_dict["click_button"])layout.addWidget(button)label = QLabel(self.language_dict["greeting"])layout.addWidget(label)container = QWidget()container.setLayout(layout)self.setCentralWidget(container)self.setWindowTitle(self.language_dict["window_title"])# 切换语言按钮switch_button = QPushButton(self.language_dict["switch_language"])layout.addWidget(switch_button)switch_button.clicked.connect(self.switch_language)def switch_language(self):# 切换语言if self.language_dict == en_dict:self.language_dict = zh_dictelse:self.language_dict = en_dict# 更新界面上的文本self.retranslateUi()def retranslateUi(self):self.setWindowTitle(self.language_dict["window_title"])self.centralWidget().children()[1].setText(self.language_dict["greeting"])self.centralWidget().children()[2].setText(self.language_dict["click_button"])self.centralWidget().children()[3].setText(self.language_dict["switch_language"])
3. 在 QApplication
中选择默认语言
if __name__ == '__main__':# 默认为英语app = QApplication([])window = MainWindow(en_dict)window.show()app.exec()
4. 完整示例代码
from PyQt6.QtWidgets import QApplication, QMainWindow, QLabel, QPushButton, QVBoxLayout, QWidget# 定义语言字典
en_dict = {"greeting": "Hello, World!","click_button": "Click me","window_title": "Main Window","switch_language": "Switch Language",
}zh_dict = {"greeting": "你好,世界!","click_button": "点击我","window_title": "主窗口","switch_language": "切换语言",
}class MainWindow(QMainWindow):def __init__(self, language_dict):super().__init__()# 保存当前语言的字典self.language_dict = language_dictlayout = QVBoxLayout()# 使用字典翻译文本button = QPushButton(self.language_dict["click_button"])layout.addWidget(button)label = QLabel(self.language_dict["greeting"])layout.addWidget(label)container = QWidget()container.setLayout(layout)self.setCentralWidget(container)self.setWindowTitle(self.language_dict["window_title"])# 切换语言按钮switch_button = QPushButton(self.language_dict["switch_language"])layout.addWidget(switch_button)switch_button.clicked.connect(self.switch_language)def switch_language(self):# 切换语言if self.language_dict == en_dict:self.language_dict = zh_dictelse:self.language_dict = en_dict# 更新界面上的文本self.retranslateUi()def retranslateUi(self):self.setWindowTitle(self.language_dict["window_title"])self.centralWidget().children()[1].setText(self.language_dict["greeting"])self.centralWidget().children()[2].setText(self.language_dict["click_button"])self.centralWidget().children()[3].setText(self.language_dict["switch_language"])if __name__ == '__main__':# 默认为英语app = QApplication([])window = MainWindow(en_dict)window.show()app.exec()
优点和缺点
优点:
- 简单快捷:如果你的应用程序不需要复杂的翻译工作,使用字典的方式是非常直接的。
- 灵活性高:可以随时根据需求修改翻译内容。
缺点:
- 扩展性差:如果应用程序的文本量增加,管理多个字典会变得不易维护。
- 无法支持标准的国际化工具:比如翻译工具和
.ts
文件生成等,这些都是 Qt 提供的标准方法,方便与其他语言开发者合作。
适用场景
- 小型应用程序,翻译的文本量较少。
- 没有复杂的翻译管理需求。
- 希望手动控制翻译内容的应用。