PyQt6应用程序中,如何实现多种语言支持
在 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, QMainWindow
class 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, QWidget
class 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, QWidget
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 = 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_dict
layout = 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_dict
else:
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_dict
layout = 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_dict
else:
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 提供的标准方法,方便与其他语言开发者合作。
适用场景
- 小型应用程序,翻译的文本量较少。
- 没有复杂的翻译管理需求。
- 希望手动控制翻译内容的应用。