PySide6/PyQt6实现中英文切换完整教程(Qt Designer + Qt Linguist + 动态切换)

前言

在桌面软件开发中,国际化(Internationalization,简称 i18n)是一个非常常见的需求。

例如:

  • MES系统

  • ERP系统

  • 工业相机软件

  • 设备上位机

  • 数据管理平台

通常需要实现:

  • 中文界面
  • 英文界面
  • 菜单切换语言
  • 不重启软件即可切换
  • Qt Designer设计界面支持翻译
  • 纯代码界面支持翻译
  • 多窗口同步切换语言

Qt官方已经提供了完整的国际化解决方案:

  • Qt Designer
  • Qt Linguist
  • pyside6-lupdate
  • pyside6-lrelease
  • QTranslator

本文将从零开始讲解完整开发流程,以及开发过程中最容易踩到的坑。


一、Qt国际化原理

Qt翻译机制如下:

text 复制代码
源代码
 ↓
tr()
 ↓
ts文件
 ↓
Qt Linguist翻译
 ↓
qm文件
 ↓
QTranslator加载
 ↓
界面显示目标语言

例如:

python 复制代码
self.setWindowTitle(self.tr("登录"))

中文环境显示:

text 复制代码
登录

英文环境显示:

text 复制代码
Login

Qt会自动根据当前加载的翻译文件进行替换。


二、纯代码开发如何支持翻译

错误写法

很多项目直接这样写:

python 复制代码
self.setWindowTitle("登录")
button.setText("确定")
menu.addMenu("文件")

这种写法Qt无法提取翻译内容。


正确写法

必须使用:

python 复制代码
self.setWindowTitle(self.tr("登录"))
button.setText(self.tr("确定"))
menu.addMenu(self.tr("文件"))

Label:

python 复制代码
label.setText(self.tr("用户名"))

ComboBox:

python 复制代码
combo.addItem(self.tr("自动模式"))

只有被 tr() 包裹的文本才会被Qt Linguist扫描到。


三、使用Qt Designer怎么办

很多项目都是:

text 复制代码
Qt Designer
 ↓
.ui
 ↓
pyside6-uic
 ↓
ui_xxx.py

Designer中直接填写中文

例如:

按钮:

text 复制代码
登录

标签:

text 复制代码
用户名

菜单:

text 复制代码
文件

保存:

text 复制代码
login.ui

转换Python代码

执行:

bash 复制代码
pyside6-uic login.ui -o ui_login.py

生成:

python 复制代码
self.pushButton.setText(QCoreApplication.translate("MainWindow", "登录", None))

Qt已经自动帮我们做好翻译支持。

因此:

使用Qt Designer时不需要自己手工加tr()

Designer会自动生成translate代码。


四、Qt Designer项目如何生成翻译文件

假设项目结构:

text 复制代码
project
│
├─ ui
│   ├─ login.ui
│   ├─ main.ui
│
├─ translations
│
├─ main.py
└─ ui_login.py

方法1:扫描UI文件

bash 复制代码
pyside6-lupdate ui/*.ui -ts translations/zh_CN.ts

生成:

text 复制代码
zh_CN.ts

方法2:扫描整个项目(推荐)

bash 复制代码
pyside6-lupdate . -ts translations/zh_CN.ts

自动扫描:

text 复制代码
.py
.ui

所有文件。

大型项目推荐这种方式。


五、Qt Linguist完整使用流程

第一步:打开Qt Linguist

命令:

bash 复制代码
pyside6-linguist

或者:

bash 复制代码
linguist

第二步:打开ts文件

菜单:

text 复制代码
File
 ↓
Open

选择:

text 复制代码
translations/zh_CN.ts

第三步:开始翻译

左侧:

text 复制代码
Source Text

显示原始文本。

例如:

text 复制代码
文件

右侧:

text 复制代码
Translation

填写:

text 复制代码
File

例如:

text 复制代码
打开

翻译:

text 复制代码
Open

例如:

text 复制代码
退出

翻译:

text 复制代码
Exit

例如:

text 复制代码
用户管理

翻译:

text 复制代码
User Management

第四步:标记完成

翻译后:

text 复制代码
Ctrl + Enter

或者点击:

text 复制代码
Done

第五步:全部翻译完成

查看左侧:

text 复制代码
Finished

确认全部完成。


第六步:发布翻译

菜单:

text 复制代码
File
 ↓
Release

或者执行:

bash 复制代码
pyside6-lrelease translations/zh_CN.ts

生成:

text 复制代码
translations/zh_CN.qm

六、ts和qm区别

很多新手容易搞混。

ts

text 复制代码
翻译源文件

可以编辑。


qm

text 复制代码
编译后的翻译文件

程序运行时加载。


例如:

text 复制代码
translations
├─ zh_CN.ts
└─ zh_CN.qm

程序加载的是:

text 复制代码
zh_CN.qm

不是:

text 复制代码
zh_CN.ts

七、加载翻译文件

主程序:

python 复制代码
translator = QTranslator()

加载:

python 复制代码
translator.load("translations/en_US.qm")

安装:

python 复制代码
app.installTranslator(translator)

八、实现中英文切换

菜单:

python 复制代码
setting.addAction(self.tr("切换中英文"))

响应:

python 复制代码
elif q.text() == self.tr("切换中英文"):
    self.switch_language()

实现:

python 复制代码
def switch_language(self):
    global translator,current_language

    app = QApplication.instance()

    if current_language == "zh_CN":
        app.removeTranslator(translator)
        translator.load("translations/en_US.qm")
        app.installTranslator(translator)
        current_language = "en_US"
    else:
        app.removeTranslator(translator)
        current_language = "zh_CN"

    self.refresh_ui()

九、为什么切换语言没效果

最常见原因:

代码写死。

例如:

python 复制代码
menu.addMenu("文件")

切换语言后仍然显示:

text 复制代码
文件

正确写法:

python 复制代码
menu.addMenu(self.tr("文件"))

十、为什么ts文件是空的

例如:

python 复制代码
button.setText("登录")

执行:

bash 复制代码
pyside6-lupdate .

生成:

xml 复制代码
<TS version="2.1">
</TS>

空文件。


原因:

没有使用:

python 复制代码
self.tr()

正确:

python 复制代码
button.setText(self.tr("登录"))

重新执行:

bash 复制代码
pyside6-lupdate .

即可提取。


十一、Designer界面翻译无效

很多人遇到:

python 复制代码
app.installTranslator(translator)

执行成功。

但是界面不变。


原因:

Designer生成界面后没有重新翻译。


解决方法:

python 复制代码
def changeEvent(self,event):
    if event.type() == QEvent.LanguageChange:
        self.retranslateUi(self)
    super().changeEvent(event)

这样收到:

python 复制代码
QEvent.LanguageChange

后会自动刷新界面。


十二、多窗口项目如何处理

例如:

text 复制代码
MainWindow
LoginWindow
SettingWindow
UserWindow

每个窗口都需要:

python 复制代码
def changeEvent(self,event):
    if event.type() == QEvent.LanguageChange:
        self.retranslateUi(self)
    super().changeEvent(event)

这样所有窗口都会同步刷新。


十三、为什么切换后闪退

很多项目这样实现:

python 复制代码
def refresh_ui(self):
    self.close()
    self.main = MainWindow()
    self.main.show()

切换语言:

text 复制代码
关闭窗口
 ↓
重新创建窗口
 ↓
重新初始化资源

如果程序包含:

python 复制代码
self.camera = Camera()

或者:

python 复制代码
self.serial = Serial()

或者:

python 复制代码
self.plc = PLC()

重新创建窗口时会再次初始化。


可能出现:

text 复制代码
open device fail
text 复制代码
serial open fail
text 复制代码
PLC connect fail

十四、工业项目为什么更容易出问题

因为存在:

text 复制代码
工业相机
PLC
串口
TCP连接
数据库连接
算法线程
消息队列

这些资源通常只能初始化一次。


错误流程:

text 复制代码
切换语言
 ↓
重新创建MainWindow
 ↓
重新初始化所有资源

容易出现:

text 复制代码
设备占用
线程异常
相机打开失败
PLC断开
串口冲突

十五、正确做法

推荐使用Qt官方方案:

text 复制代码
QTranslator
 ↓
LanguageChange
 ↓
retranslateUi

只刷新界面文本。

不重建窗口。


优势:

text 复制代码
相机不断流
PLC不断线
线程不停
数据库不断开
无闪屏

十六、推荐项目结构

text 复制代码
project
│
├─ ui
│   ├─ login.ui
│   ├─ main.ui
│   ├─ setting.ui
│
├─ translations
│   ├─ zh_CN.ts
│   ├─ zh_CN.qm
│   ├─ en_US.ts
│   └─ en_US.qm
│
├─ main.py
├─ login.py
├─ setting.py
└─ resource.py

十七、推荐开发规范

所有显示文字:

python 复制代码
self.tr("文件")
self.tr("登录")
self.tr("用户管理")
self.tr("系统设置")

不要直接写:

python 复制代码
"文件"
"登录"
"用户管理"

统一管理:

python 复制代码
translator
current_language

Designer界面:

python 复制代码
retranslateUi()

动态刷新:

python 复制代码
changeEvent()

十八、完整开发流程总结

text 复制代码
Qt Designer设计界面
        ↓
保存.ui文件
        ↓
pyside6-uic生成Python代码
        ↓
所有文本使用tr()/translate
        ↓
pyside6-lupdate扫描项目
        ↓
生成ts文件
        ↓
Qt Linguist翻译
        ↓
生成qm文件
        ↓
QTranslator加载
        ↓
installTranslator
        ↓
LanguageChange
        ↓
retranslateUi
        ↓
界面实时切换语言

十九、常见问题汇总

问题 原因 解决方法
ts文件为空 没有使用tr() 使用self.tr()
qm加载失败 路径错误 检查translations目录
菜单不翻译 文本写死 使用self.tr()
Designer界面不翻译 未调用retranslateUi 重写changeEvent
多窗口不同步 子窗口未处理LanguageChange 每个窗口实现changeEvent
切换后闪退 重建窗口导致资源异常 使用LanguageChange机制
相机打开失败 设备重复初始化 不重建设备对象
PLC断线 窗口重建 通信对象单例化
新增文本不翻译 未重新执行lupdate 重新生成ts
修改翻译无效 未执行lrelease 重新生成qm

二十、结语

Qt官方国际化方案已经非常成熟。对于小型项目,可以采用"切换语言后重建窗口"的方式快速实现;对于大型项目、工业软件、视觉检测软件、MES系统、设备上位机等,建议采用Qt官方推荐的 LanguageChange + retranslateUi() 机制,只刷新界面文本,不重新创建窗口和设备资源。

这样既能实现实时切换语言,又能避免设备断开、线程异常、界面闪烁等问题,能够满足绝大多数商业项目的国际化需求。

相关推荐
星辰_mya1 小时前
ThreadLocal之微服务链路追踪
java·开发语言·前端
咸鱼翻身小阿橙1 小时前
文件读写 + Qt Model/View + 自定义分页+搜索过滤
java·数据库·qt
眠りたいです1 小时前
现代C++:C++17中的新语言特性
开发语言·c++·c++17
一只旭宝1 小时前
【C++入门精讲17】序列容器
开发语言·c++
Demon1_Coder1 小时前
Day1-SpringAI-1.0.0版本
java·开发语言·前端
郝学胜-神的一滴1 小时前
Qt 高级开发 021:零基础吃透 QVBoxLayout 垂直布局
开发语言·c++·qt·程序人生·用户界面
basketball6161 小时前
C++进阶:2. std::move 和 std::forward 函数
java·开发语言·c++
_oP_i1 小时前
105、word 出现 {TOCO“1-2“HZ}
开发语言·c#·word
yong99901 小时前
基于MATLAB的雷达数字信号处理
开发语言·matlab·信号处理