1. Visão geral da função
Alguns softwares precisam desenvolver versões de interface multilíngue, como versões em chinês e inglês.
O desenvolvimento do aplicativo de interface multilíngue PyQt5 inclui principalmente as seguintes etapas.
(1) Use um idioma ao projetar visualmente formulários de IU, como o chinês.
(2) Para programas escritos em Python baseados em PyQt5, onde quer que strings sejam usadas, as strings precisam ser encapsuladas com a função de classe QCoreApplication.translate().
(3) Crie um arquivo de configuração para o arquivo fonte que precisa ser traduzido, por exemplo chamado transSources.txt, o formato do arquivo é semelhante ao arquivo de configuração do projeto do Qt Creator, adicione o arquivo .ui e o arquivo .py que precisa a ser traduzido e especifique os arquivos de tradução gerados necessários (arquivos .ts).
(4) Use o software ferramenta pylupdate5.exe do PyQt5 para compilar o arquivo transSources.txt para gerar vários arquivos de tradução especificados.
(5) Abra o arquivo de tradução gerado com o software Qt Linguist. O arquivo de tradução extrai todas as strings da interface e do programa e traduz essas strings para o idioma necessário, por exemplo, traduz todas as strings chinesas para o inglês.
(6) Após concluir a tradução no software Linguist, use a função de publicação do software Linguist para exportar um arquivo de recurso de idioma mais compacto (arquivo .qm) para uso no programa.
(7) Crie um objeto QTranslator no programa e carregue um determinado arquivo .qm e, em seguida, use a função de classe QCoreApplication installTranslator() para carregar o objeto QTranslator, então você pode usar a interface de exibição de conteúdo do arquivo .qm para implementar diferentes interfaces de linguagem.
2. A classe principal e função
QCoreApplication: use a função translate() para encapsular a string
text = QCoreApplication.translate("QmyMainWindow","文件名:")
self.ui.statusBar.showMessage(text)
translate(context, sourceText): O primeiro parâmetro é o contexto, que é o nome da classe onde o código está localizado, e o segundo parâmetro é a string a ser traduzida.
Notas sobre o uso da função translate():
(1) Tente usar constantes de string em vez de variáveis de string.
#这种写法错误
textFile = "选择的文件名"
text = QCoreApplication.translate("QmyMainWindow", textFile)
self.ui.statusBar.showMessage(text)
#这种写法正确
text = QCoreApplication.translate('QmyMainWindow', '选择的文件名')
self.ui.statusBar.showMessage(text)
(2) Ao usar uma variável de string, ela precisa ser marcada com a macro QT_TRANSLATE_NOOP(). A
macro QT_TRANSLATE_NOOP() no módulo PyQt5.QtCore é geralmente usada para a inicialização da lista de strings.
from PyQt5.QtCore import QT_TRANSLATE_NOOP
cityList = [QT_TRANSLATE_NOOP("QmyMainWindow", "北京市"),
QT_TRANSLATE_NOOP("QmyMainWindow", "上海市"),
QT_TRANSLATE_NOOP("QmyMainWindow", "四川省")]
text = QCoreApplication.translate("QmyMainWindow",cityList[0])
(3) A string dinâmica emendada não pode ser usada em translate().
As duas linhas a seguir para gerar o texto da variável string podem ser executadas, e a string emendada também pode ser exibida na interface, mas ao gerar a tradução arquivo, ele não pode extrair a string nele.
#无法翻译
num = 100
text = QCoreApplication.translate("QmyMainWindow", "第" + str(num) + "行")
text = QCoreApplication.translate("QmyMainWindow", "第%d行" %num)
self.ui.statusBar.showMessage(text)
removerTradutor(tradutor):
3. Código detalhado
A interface chinesa de tempo de execução no exemplo é mostrada na figura acima.
Existem dois botões para seleção do idioma da interface na barra de ferramentas. Quando o botão "Inglês" é clicado para mudar para inglês, a interface é mostrada na figura abaixo.
Quando o programa estiver em execução, clique nos dois botões na barra de ferramentas para alternar entre as interfaces em chinês e inglês, e o idioma atualmente definido será salvo automaticamente no registro, e o último idioma da interface será usado automaticamente quando o programa iniciar na próxima vez .
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow,QActionGroup
from PyQt5.QtGui import QTextCharFormat, QFont
from PyQt5.QtCore import (Qt, pyqtSlot,QCoreApplication,
QTranslator,QSettings,QT_TRANSLATE_NOOP)
from ui_MainWindow import Ui_MainWindow
class QmyMainWindow(QMainWindow):
_tr = QCoreApplication.translate #替代符
def __init__(self, parent=None):
super().__init__(parent) #调用父类构造函数,创建窗体
self.ui = Ui_MainWindow() #创建UI对象
self.ui.setupUi(self) #构造UI界面
text = self._tr("QmyMainWindow","文件名: ")
self.ui.statusBar.showMessage(text)
actionGroup = QActionGroup(self)
actionGroup.addAction(self.ui.actLang_CN)
actionGroup.addAction(self.ui.actLang_EN)
actionGroup.setExclusive(True) #互斥型分组
self.__translator = None #QTranslator对象
self.setCentralWidget(self.ui.textEdit)
## ============自定义功能函数================================
def setTranslator(self,translator,Language):
self.__translator = translator
if Language=="EN":
self.ui.actLang_EN.setChecked(True)
else:
self.ui.actLang_CN.setChecked(True)
A função personalizada setTranslator(self, tradutor, Language) é usada para passar o objeto QTranslator e o último tipo de idioma da interface para a janela principal quando o aplicativo é iniciado. Chame essa função no código que cria o aplicativo, não no construtor da classe QmyMainWindow.
Gerando arquivos de tradução: Após encapsular as strings a serem traduzidas no programa, você pode usar o software ferramenta pylupdate5 do PyQt5 para gerar arquivos de tradução (.ts) . pylupdate5.exe é um software ferramenta que é instalado automaticamente quando o PyQt5 é instalado.O diretório onde o software está localizado é adicionado à variável de ambiente PATH do sistema Windows, para que o pylupdate5 possa ser executado diretamente no ambiente cmd.
Para executar o programa pylupdate5, você deve primeiro escrever um arquivo de configuração para o projeto de exemplo. Este arquivo de configuração é semelhante ao arquivo de projeto Qt Creator, então você pode usar ".pro" como sufixo do arquivo. Mas clicar duas vezes no arquivo .pro abrirá o Qt Creator, que não é fácil de modificar, então o nomeamos diretamente como transSources.txt, e o seguinte é o conteúdo deste arquivo:
## transSources.txt 用于生成翻译文件(.ts)文件的配置文件
## .ts是需要生成的翻译资源文件
TRANSLATIONS =appLang_CN.ts\
appLang_EN.ts
## SOURCES指定需要翻译的 .py、 .pyw文件
SOURCES += myMainWindow.py
## FORMS指定需要翻译的 .ui文件
FORMS +=MainWindow.ui
Existem 3 partes neste arquivo.
(1) TRANSLATIONS especifica o nome do arquivo de tradução a ser gerado, vários arquivos de tradução podem ser gerados, um arquivo é um idioma, use "\" para continuar a linha quando houver vários arquivos.
(2) SOURCES especifica os arquivos de programa de origem que precisam ser traduzidos, ou seja, os arquivos .py e .pyw do projeto. Se houver vários arquivos, use "\" para continuar a linha.
(3) FORMS especifica o arquivo de interface .ui que precisa ser traduzido.
Você pode traduzir arquivos .ui e também traduzir arquivos .py compilados a partir de arquivos .ui
TRANSLATIONS =appLang_CN.ts\
appLang_EN.ts
SOURCES += myMainWindow.py\
ui_MainWindow.py
Depois de preparar o arquivo transSources.txt, use pylupdate5 para compilar e gerar o arquivo .ts especificado. Para facilitar a execução do comando pylupdate5, escreva um arquivo em lote transUpdate.bat, o seguinte é o conteúdo deste arquivo:
rem 用pylupdate5.exe 编译transSources.txt文件,生成.ts文件
pylupdate5 -noobsolete transSources.txt
O parâmetro -noobsolete no comando significa excluir alguns itens inúteis do arquivo de tradução.
Clique duas vezes no arquivo transUpdate.bat no Windows Explorer para executar o comando de compilação. Se os arquivos appLang_CN.ts e appLang_EN.ts não existirem no diretório, esses dois arquivos serão gerados. Se os arquivos já existirem, o conteúdo desses dois arquivos será atualizado. Portanto, após modificar a interface e o programa, o os arquivos de tradução podem ser gerados novamente sem excluir os existentes.
Use o Qt Linguist para traduzir arquivos: os arquivos de tradução gerados appLang_CN.ts e appLang_EN.ts contêm todas as strings na interface da interface do usuário e nos programas Python, e use o Qt Linguist para traduzir essas strings nas versões de idioma necessárias. O software Qt Linguist pode ser encontrado no grupo de programas Qt.
appLang_CN.ts é o arquivo de tradução da interface chinesa, pois a interface do programa fonte é projetada em chinês, portanto não há necessidade de traduzi-la. appLang_EN.ts é um arquivo de tradução em inglês, que precisa traduzir todas as strings chinesas extraídas para o inglês.
Abra o arquivo appLang_EN.ts no software Linguist. Ao abrir um arquivo .ts pela primeira vez, o Linguist exibirá a caixa de diálogo de configuração de idioma conforme mostrado na figura abaixo, que é usada para definir o idioma de destino e o país/região. Esta caixa de diálogo também pode ser acessada através do item de menu "Editar" → "Configurações do arquivo de tradução..." do menu principal do Linguist. appLang_EN.ts é um arquivo de tradução para a interface em inglês, então selecione o idioma inglês e selecione "qualquer país" para o país/região.
Depois de abrir o arquivo appLang_EN.ts, a interface do software Linguist é mostrada abaixo. A janela ou classe da UI no projeto está listada na lista "Contexto" à esquerda, onde MainWindow é a classe de interface no arquivo da UI e QmyMainWindow é a classe de lógica de negócios do formulário. A lista "String" lista as strings extraídas de um objeto de contexto à esquerda, e a "Frase e Formulário" à direita exibe a visualização da interface da janela ou o segmento de código onde a string aparece no programa de origem.
Chame o arquivo de tradução para alterar o idioma da interface: Para usar o arquivo .qm no programa, você precisa criar um objeto QTranslator e carregar o arquivo .qm e, em seguida, usar a função de classe QCoreApplication installTranslator() para instalar o tradutor. Esse processo é concluído quando o aplicativo é iniciado, portanto, escreva o código na parte do programa de teste do arquivo myMainWindow.py da seguinte maneira:
## ===========窗体测试程序=================================
if __name__ == "__main__": #用于当前窗体测试
app = QApplication(sys.argv) #创建GUI应用程序
# 读取注册表里的语言设置
QCoreApplication.setOrganizationName("mySoft")
QCoreApplication.setApplicationName("Demo11_1")
##organization="mySoft" #用于注册表
##appName="Demo11_1" #HKEY_CURRENT_USER/Software/mySoft/Demo11_1
regSettings = QSettings(QCoreApplication.organizationName(),
QCoreApplication.applicationName()) #创建
Language = regSettings.value("Language","EN") #读取Language键的值,缺省"EN"
trans = QTranslator()
if Language=="EN":
trans.load("appLang_EN.qm")
else:
trans.load("appLang_CN.qm")
QCoreApplication.installTranslator(trans)
form = QmyMainWindow() #创建窗体
form.setTranslator(trans,Language) #赋值给QmyMainWindow的类变量translator
form.show()
sys.exit(app.exec_())
A função de leitura de chaves de registro é usada aqui. QCoreApplication possui diversas funções de classe para definir e representar algumas informações globais.
setOrganizationName(orgName) e OrganizationName(): usados para definir e retornar o nome da organização.
setApplicationName(appName) e applicationName(): usados para definir e retornar o nome do aplicativo.
QSettings é uma classe usada para ler e salvar configurações de aplicativos. A localização dessas configurações está relacionada à plataforma. Na plataforma Windows, é o registro, e nos sistemas macOS e iOS, é o arquivo de lista de propriedades. De acordo com as configurações do programa, o diretório no registro correspondente ao regSettings criado é:
HKEY_CURRENT_USER/Software/mySoft/Demo11_1
Use a função value(key, defaultValue) de QSettings para ler o valor da chave key, se a chave não existir, retorne o valor padrão defaultValue.
A classe QTranslator é uma classe tradutora, sua principal função é carregar o arquivo .qm e, em seguida, instalá-lo no programa aplicativo pela função de classe installTranslator() de QCoreApplication para realizar a interface de idioma correspondente.
O código também chama a função de interface personalizada setTranslator() da classe QmyMainWindow, que deve passar o objeto da classe QTranslator criado e o tipo de idioma atual para o formulário do objeto da janela principal, para que a janela principal possa salvar o objeto QTranslator.
Depois de fazer esse trabalho quando o programa é iniciado, o último idioma da interface pode ser usado quando o programa é iniciado. Quando o programa estiver em execução, clique no botão "Chinês" ou "Inglês" na barra de ferramentas para mudar o idioma da interface em tempo real. Os códigos de função de slot associados a esses dois botões são os seguintes:
## ===========由connectSlotsByName() 自动连接的槽函数=====================
@pyqtSlot() ##英语界面
def on_actLang_EN_triggered(self):
QCoreApplication.removeTranslator(self.__translator)
self.__translator = QTranslator()
self.__translator.load("appLang_EN.qm")
QCoreApplication.installTranslator(self.__translator)
self.ui.retranslateUi(self)
regSettings = QSettings(QCoreApplication.organizationName(),
QCoreApplication.applicationName())
regSettings.setValue("Language","EN") #保存设置
@pyqtSlot() ##汉语界面
def on_actLang_CN_triggered(self):
QCoreApplication.removeTranslator(self.__translator)
self.__translator = QTranslator()
self.__translator.load("appLang_CN.qm")
QCoreApplication.installTranslator(self.__translator)
self.ui.retranslateUi(self)
regSettings = QSettings(QCoreApplication.organizationName(),
QCoreApplication.applicationName())
regSettings.setValue("Language","CN") #保存设置
@pyqtSlot(bool) ##设置粗体
def on_actFont_Bold_triggered(self, checked):
fmt = self.ui.textEdit.currentCharFormat()
if (checked == True):
fmt.setFontWeight(QFont.Bold)
else:
fmt.setFontWeight(QFont.Normal)
self.ui.textEdit.mergeCurrentCharFormat(fmt)
@pyqtSlot(bool) ##设置斜体
def on_actFont_Italic_triggered(self, checked):
fmt=self.ui.textEdit.currentCharFormat()
fmt.setFontItalic(checked)
self.ui.textEdit.mergeCurrentCharFormat(fmt)
@pyqtSlot(bool) ##设置下划线
def on_actFont_UnderLine_triggered(self,checked):
fmt = self.ui.textEdit.currentCharFormat()
fmt.setFontUnderline(checked)
self.ui.textEdit.mergeCurrentCharFormat(fmt)
def on_textEdit_copyAvailable(self, avi): ##文本框内容可copy
self.ui.actEdit_Cut.setEnabled(avi)
self.ui.actEdit_Copy.setEnabled(avi)
self.ui.actEdit_Paste.setEnabled(self.ui.textEdit.canPaste())
def on_textEdit_selectionChanged(self): ##文本选择内容发生变化
fmt=self.ui.textEdit.currentCharFormat()
self.ui.actFont_Bold.setChecked(fmt.font().bold())
self.ui.actFont_Italic.setChecked(fmt.fontItalic())
self.ui.actFont_UnderLine.setChecked(fmt.fontUnderline())
def on_textEdit_customContextMenuRequested(self,pos): ##标准右键菜单
#创建一个内建的标准的编辑功能快捷菜单
popMenu = self.ui.textEdit.createStandardContextMenu()
popMenu.exec(pos)
@pyqtSlot(bool) ##设置工具栏按钮样式
def on_actSys_ToggleText_triggered(self,checked):
btnStyle = Qt.ToolButtonIconOnly
if(checked):
btnStyle = Qt.ToolButtonTextUnderIcon
self.ui.mainToolBar.setToolButtonStyle(btnStyle)
def on_actFile_New_triggered(self): ##新建文件,不实现具体功能
text = self._tr("QmyMainWindow","新建文件")
self.ui.statusBar.showMessage(text)
def on_actFile_Open_triggered(self): ##打开文件,不实现具体功能
text=self._tr("QmyMainWindow","打开的文件:")
self.ui.statusBar.showMessage(text)
def on_actFile_Save_triggered(self): ##保存文件,不实现具体功能
text=self._tr("QmyMainWindow","文件已保存")
self.ui.statusBar.showMessage(text)
## =============自定义槽函数===============================
As funções e códigos dessas duas funções de slot são semelhantes. Primeiro, remova o tradutor original. Embora vários tradutores possam ser instalados no aplicativo, apenas o último instalado é usado. Geralmente, é melhor instalar apenas um tradutor. Em seguida, crie um tradutor, carregue o arquivo .qm, instale-o no aplicativo e salve o tipo de idioma da interface atual no registro.
Função retranslateUi(): permite que a interface seja traduzida novamente. Se esta instrução não for executada, o idioma da interface não poderá ser alterado em tempo real.
Abra o arquivo ui_MainWindow.py e você poderá ver o código da função retranslateUi() definida na classe Ui_MainWindow. Apenas parte do código é mostrada abaixo:
class Ui_MainWindow(object):
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
self.menu_E.setTitle(_translate("MainWindow", "编辑(&E)"))
self.menu_F.setTitle(_translate("MainWindow", "格式(&M)"))
self.menu.setTitle(_translate("MainWindow", "界面语言"))
self.menu_F_2.setTitle(_translate("MainWindow", "文件(&F)"))
self.actEdit_Cut.setText(_translate("MainWindow", "剪切"))
self.actEdit_Cut.setShortcut(_translate("MainWindow", "Ctrl+X"))
self.actEdit_Copy.setText(_translate("MainWindow", "复制"))
Pode-se observar que a função da função retranslateUi() é reunir todas as configurações estáticas de strings na interface e encapsulá-las com a função QtCore.QCoreApplication.translate(). Portanto, ao mudar de idioma, você precisa chamar a função retranslateUi() do formulário para retraduzir. A função retranslateUi() é chamada na função setupUi() da classe Ui_MainWindow, portanto a interface será traduzida automaticamente ao criar um novo formulário.
Se um aplicativo tiver vários formulários, o setupUi() chamado ao criar um novo formulário será traduzido automaticamente. Mas se um formulário já existir na memória, você precisará chamar explicitamente sua função retranslateUi() ao exibir o formulário após mudar de idioma. Claro, é possível emitir sinais ao mudar de idioma e usar funções de slot para responder, mas isso adicionará sobrecarga e complexidade adicionais, especialmente quando um aplicativo tiver muitas janelas. Portanto, depois que o idioma da interface é selecionado para software de grande escala, ele geralmente entra em vigor na próxima vez que for iniciado.