QtLingusit国际化UI

Arya Lv3

🍕前言

去年总监提了个想法,想把工具进行国际化和本地化,这样各个地方的团队都可以更舒适的使用工具。我研究了这个方向也有一段时间了,算上maya中的国际化案例,我总共总结了几个流程和一些小demo。

UI界面是通过python代码写的

😃准备流程

对于准备流程来说,我们需要通过ui文件翻译的qm文件,而qm文件是由Qt Linguist软件通过.ts文件进行翻译后发布的
根据写ui的不同方式,我总结了三个流程,接下来从简单到复杂地来进行讲解:
1.通过.ui文件转写.py文件,然后生成.ts文件,直接在命令行调用两条命令就行了

1
2
3
python -m PyQt5.uic.pyuic .ui file -o .py file

pylupdate5 .py file -ts .ts file

2.用代码写的UI,首先需要确保的是UI中需要翻译的文本被Qt中的tr函数“修饰”过。也就是说,UI中的对于文本的修饰可以用:

1
2
1.QtCore.QCoreApplication.translate("{}".format(context),"{}".format(text))
2.self.tr("{}".format(text))

然后用命令行对py文件进行转换

1
pylupdate5 .py file -ts .ts file 

3.直接在代码里使用.ui文件(通过uic UILoad或者uic.load),在命令行里需要对py文件和ts文件同时进行转写生成ts文件

1
pylupdate5 .py file .ui file -ts .ts file

转换之后生成的ts文件,需要用Qt Linguist软件对它进行翻译,生成对应的qm文件(一般发布后的qm文件名称和ts文件的名称一样)
Usage of .ts file

📃在代码中的使用流程

1.创建QTranslator

2.将QTranslator安装到正在运行的QApplication上

3.通过self.tr()对文本进行翻译

1.通过qt designer生成.ui文件,ui文件转写为python:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'test_ui.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(489, 394)
self.verticalLayout_2 = QtWidgets.QVBoxLayout(Form)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.verticalLayout = QtWidgets.QVBoxLayout()
self.verticalLayout.setObjectName("verticalLayout")
self.label = QtWidgets.QLabel(Form)
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.label.setObjectName("label")
self.verticalLayout.addWidget(self.label)
self.English_btn = QtWidgets.QPushButton(Form)
self.English_btn.setObjectName("English_btn")
self.verticalLayout.addWidget(self.English_btn)
self.Chinese_btn = QtWidgets.QPushButton(Form)
self.Chinese_btn.setObjectName("Chinese_btn")
self.verticalLayout.addWidget(self.Chinese_btn)
self.Hindi_btn = QtWidgets.QPushButton(Form)
self.Hindi_btn.setObjectName("Hindi_btn")
self.verticalLayout.addWidget(self.Hindi_btn)
self.verticalLayout_2.addLayout(self.verticalLayout)

self.retranslateUi(Form)
#QtCore.QMetaObject.connectSlotsByName(Form)

def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
self.label.setText(_translate("Form", "Hello,world"))
self.English_btn.setText(_translate("Form", "English"))
self.Chinese_btn.setText(_translate("Form", "中文"))
self.Hindi_btn.setText(_translate("Form", "सोच।"))







import sys

from test_ui import Ui_Form

from PyQt5 import QtWidgets
from PyQt5.QtCore import QTranslator


class Linguist_win(QtWidgets.QMainWindow, Ui_Form):
def __init__(self):
super(Linguist_win, self).__init__()
self.resize(250, 200)
self.setWindowTitle("Linguist_win")
self.widget = QtWidgets.QWidget()
self.setupUi(self.widget)
self.setCentralWidget(self.widget)

self.English_btn.clicked.connect(self.trigger_English)
self.Chinese_btn.clicked.connect(self.trigger_Chinese)
self.Hindi_btn.clicked.connect(self.trigger_Hindi)

self.trans = QTranslator()

def trigger_English(self):
self.trans.load('en')

app = QtWidgets.QApplication.instance()
app.installTranslator(self.trans)
self.retranslateUi(self)

def trigger_Chinese(self):
self.trans.load('zh_CN')

app = QtWidgets.QApplication.instance()
app.installTranslator(self.trans)
self.retranslateUi(self)

def trigger_Hindi(self):
self.trans.load('hi_IN')

app = QtWidgets.QApplication.instance()
app.installTranslator(self.trans)
self.retranslateUi(self)


if __name__=="__main__":
app=QtWidgets.QApplication(sys.argv)
win=Linguist_win()
win.show()
sys.exit(app.exec_())

2.用python写的ui界面(官方案例-修改版):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
'''
Description: 加载中文翻译文件,使工具初始化为中文,其中中文的qm翻译文件需要用命令行进行生成
'''
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause

import sys
from PySide6.QtCore import (QItemSelection, QLibraryInfo, QLocale, QTranslator,
Slot)
from PySide6.QtWidgets import (QAbstractItemView, QApplication, QListWidget,
QMainWindow)
import linguist_rc # noqa: F401


class Window(QMainWindow):
def __init__(self):
super().__init__()
file_menu = self.menuBar().addMenu(self.tr("&File"))
quit_action = file_menu.addAction(self.tr("Quit"))
quit_action.setShortcut(self.tr("CTRL+Q"))
quit_action.triggered.connect(self.close)
help_menu = self.menuBar().addMenu(self.tr("&Help"))
about_qt_action = help_menu.addAction(self.tr("About Qt"))
about_qt_action.triggered.connect(qApp.aboutQt) # noqa: F821

self._list_widget = QListWidget()
self._list_widget.setSelectionMode(QAbstractItemView.MultiSelection)
self._list_widget.selectionModel().selectionChanged.connect(self.selection_changed)
self._list_widget.addItem("C++")
self._list_widget.addItem("Java")
self._list_widget.addItem("Python")
self.setCentralWidget(self._list_widget)

@Slot(QItemSelection, QItemSelection)
def selection_changed(self, selected, deselected):
count = len(self._list_widget.selectionModel().selectedRows())
message = self.tr("%n language(s) selected", "", count)
self.statusBar().showMessage(message)


if __name__ == '__main__':
app = QApplication(sys.argv)
path = QLibraryInfo.path(QLibraryInfo.TranslationsPath)
translator = QTranslator(app)
if translator.load("D://Arya/zh_CN"): #加载.qm文件的绝对路径
app.installTranslator(translator)
# print(translator.isEmpty())
# print(translator.filePath())
window = Window()
window.show()
sys.exit(app.exec())

3.用qtdesigner设计的ui界面,然后通过.py和.ui文件一起生成ts文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import sys
from PyQt5 import QtWidgets
from PyQt5 import QtCore
from PyQt5 import uic


class Linguist_Win(QtWidgets.QMainWindow):
def __init__(self):
super(Linguist_Win,self).__init__()
ui_path = r"D:\Arya\main_ui.ui"
uic.loadUi(ui_path, self)
self.setCentralWidget(self.main_widget)


if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
translator = QtCore.QTranslator(app)
if translator.load("D://Arya/zh_CN"): #加载.qm文件的绝对路径
app.installTranslator(translator)
window = Linguist_Win()
window.show()
sys.exit(app.exec())

4.maya案例

在maya中翻译的唯一区别就是,因为maya app已经在运行,所以我们要拿到正在运行的app的实例,然后再安装QTranslator。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import os

import maya.OpenMayaUI as omui
from shiboken2 import wrapInstance
from PySide2 import (
QtWidgets,
QtCore
)
from PySide2.QtUiTools import QUiLoader


TRANSLATOR = QtCore.QTranslator()
# Path to the referenced file used,the qm file used
# for translation(TRANS_CHINESE_FILE_PATH,TRANS_HINDI_FILE_PATH)
# must be an absolute path.
"""if you are test this demo, please change the 'TRANS_CHINESE_FILE_PATH' to the absolute path where the translation files
are saved
"""
UI_PATH = r"D:\Arya\main_ui.ui"

TRANS_ENGLISH_FILE_PATH = r"D:\Arya\en_US"

TRANS_CHINESE_FILE_PATH = r"D:\Arya\zh_CN"



def get_maya_window_ptr():
ptr = omui.MQtUtil.mainWindow()
maya_win = wrapInstance(int(ptr), QtWidgets.QMainWindow)
return maya_win


class Linguist_win(QtWidgets.QMainWindow):
def __init__(self, parent = get_maya_window_ptr()):
super(Linguist_win, self).__init__(parent = parent)
# the ui needs to be create in a method and it will
# be reload when translating
self._ui()

def _ui(self):
"""load UI to self from .ui file and set the button connections
and window title
"""
loader = QUiLoader()
self.ui_file = QtCore.QFile(UI_PATH)
self.ui_file.open(QtCore.QIODevice.ReadOnly)
self.ui_widget = loader.load(self.ui_file, self)
#ui_file.close()

self.setCentralWidget(self.ui_widget)
self.setWindowTitle("LingusitWindow")
self.ui_widget.Chinese_btn.clicked.connect(self.translate)
self.ui_widget.Hindi_btn.clicked.connect(self.translate)
self.ui_widget.English_btn.clicked.connect(self.translate)


def translate(self):
"""
to translate the UI to English
"""
# if the path is exist or if the translation file is successfully loaded
# install the translator to the app instance
# and reload the ui then show it
print(self.sender())
if self.sender() == self.ui_widget.English_btn:
if TRANSLATOR.load(TRANS_ENGLISH_FILE_PATH):
print("English success")
elif self.sender() == self.ui_widget.Chinese_btn:
if TRANSLATOR.load(TRANS_CHINESE_FILE_PATH):
print("Chinese success")
self._ui()
self.show()


def main():
app = QtWidgets.QApplication.instance()
app.installTranslator(TRANSLATOR)
win = Linguist_win()
win.show()

探索了几个月还是有所收获的,希望研究了那么久的方法可以在项目中大量实现吧。

  • 标题: QtLingusit国际化UI
  • 作者: Arya
  • 创建于 : 2024-03-08 09:00:00
  • 更新于 : 2024-03-12 19:26:38
  • 链接: https://aryagala0.github.io/2024/03/08/PyQt/使用QtLinguist对UI文件进行翻译/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
 评论