Интернационализация (перевод) диалога и главного окна в приложении pyqt5 - PullRequest
0 голосов
/ 16 ноября 2018

Я пытаюсь перевести мое небольшое приложение, написанное в pyside2 / pyqt5, на несколько языков, например, на китайский. После поиска в Google мне удалось изменить главное окно на китайское после выбора в меню -> язык -> китайский. Тем не менее, всплывающее диалоговое окно из меню -> вариант по-прежнему остается английской версией. Кажется, информация о переводе не передается в диалог. Как мне это решить?

По сути, я создаю два файла пользовательского интерфейса в конструкторе и преобразую в два файла Python: один mainui.py и один dialogui.py. Затем я конвертирую два файла Python в один * .ts файл, используя

pylupdate5 -verbose mainui.py dialogui.py -ts zh_CN.ts

после этого в лингвист вводим перевод слов. Я вижу элементы в диалоге, что означает, что эта информация не пропущена. Затем я выпускаю файл как файл zh_CN.qm. Все эти вспомогательные файлы я прикрепил ниже, используя google drive.

Вспомогательные файлы для вопроса

Основной файл как

import os
import sys

from PySide2 import QtCore, QtGui, QtWidgets
from mainui import Ui_MainWindow

from dialogui import Ui_Dialog

class OptionsDialog(QtWidgets.QDialog,Ui_Dialog):
    def __init__(self,parent):
        super().__init__(parent)
        self.setupUi(self)
        self.retranslateUi(self)


class MainWindow(QtWidgets.QMainWindow,Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.actionConfigure.triggered.connect(self.showdialog)
        self.actionChinese.triggered.connect(self.change_lang)

    def showdialog(self):
        dlg = OptionsDialog(self)
        dlg.exec_()

    def change_lang(self):
        trans = QtCore.QTranslator()
        trans.load('zh_CN')
        QtCore.QCoreApplication.instance().installTranslator(trans)
    self.retranslateUi(self)



if __name__=='__main__':
    app = QtWidgets.QApplication(sys.argv)
    mainWin = MainWindow()
    mainWin.show()
    ret = app.exec_()
    sys.exit(ret)

Я думаю, что это должно быть типичной задачей, потому что почти ни у одного приложения не будет только главного окна.

1 Ответ

0 голосов
/ 16 ноября 2018

Необходимо переписать метод changeEvent() и вызвать retranslateUi(), когда событие имеет тип QEvent::LanguageChange, с другой стороны, объект QTranslator должен быть членом класса, но он будет удален, и он не будет существовать при вызове метода changeEvent().

Наконец, предполагая, что меню Language используется для установления только переводов, возможный вариант - установить имя .qm в качестве данных QAction s и использовать триггерный метод QMenu, как я показываю ниже:

from PySide2 import QtCore, QtGui, QtWidgets
from mainui import Ui_MainWindow

from dialogui import Ui_Dialog

class OptionsDialog(QtWidgets.QDialog,Ui_Dialog):
    def __init__(self,parent):
        super().__init__(parent)
        self.setupUi(self)

    def changeEvent(self, event):
        if event.type() == QtCore.QEvent.LanguageChange:
            self.retranslateUi(self)
        super(OptionsDialog, self).changeEvent(event)

class MainWindow(QtWidgets.QMainWindow,Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.m_translator = QtCore.QTranslator(self)
        self.actionConfigure.triggered.connect(self.showdialog)
        self.menuLanguage.triggered.connect(self.change_lang)
        # set translation for each submenu
        self.actionChinese.setData('zh_CN')

    @QtCore.Slot()
    def showdialog(self):
        dlg = OptionsDialog(self)
        dlg.exec_()

    @QtCore.Slot(QtWidgets.QAction)
    def change_lang(self, action):
        QtCore.QCoreApplication.instance().removeTranslator(self.m_translator)
        if self.m_translator.load(action.data()):
            QtCore.QCoreApplication.instance().installTranslator(self.m_translator)

    def changeEvent(self, event):
        if event.type() == QtCore.QEvent.LanguageChange:
            self.retranslateUi(self)
        super(MainWindow, self).changeEvent(event)

if __name__=='__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    mainWin = MainWindow()
    mainWin.show()
    ret = app.exec_()
    sys.exit(ret)
...