Как динамически менять языки (переводы) на PyQt5? - PullRequest
0 голосов
/ 17 ноября 2018

Интересно, можно ли динамически изменять языки (переводы), не используя qt designer для создания пользовательского интерфейса?Это означает, что я не хочу использовать функцию retranslateUi () для обновления интерфейса программы.

Вот мой код, но я застрял в строках, помеченных # 1 # 2 # 3.Не знаю, что я должен использовать для обновления интерфейса.

import sys
from PyQt5.QtCore import Qt, QTranslator
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel, 
QComboBox, QVBoxLayout


class Demo(QWidget):
    def __init__(self):
        super(Demo, self).__init__()
        self.button = QPushButton(self.tr('Start'), self)
        self.label = QLabel(self.tr('Hello, World'), self)
        self.label.setAlignment(Qt.AlignCenter)

        self.combo = QComboBox(self)
        self.combo.addItem('English')
        self.combo.addItem('中文')
        self.combo.addItem('français')
        self.combo.currentTextChanged.connect(self.change_func)

        self.trans = QTranslator(self)

        self.v_layout = QVBoxLayout()
        self.v_layout.addWidget(self.combo)
        self.v_layout.addWidget(self.button)
        self.v_layout.addWidget(self.label)
        self.setLayout(self.v_layout)

    def change_func(self):
        print(self.combo.currentText())
        if self.combo.currentText() == '中文':
            self.trans.load('eng-chs')
            _app = QApplication.instance()
            _app.installTranslator(self.trans)
            # 1

        elif self.combo.currentText() == 'français':
            self.trans.load('eng-fr')
            _app = QApplication.instance()
            _app.installTranslator(self.trans)
            # 2

        else:
            _app = QApplication.instance()
            _app.removeTranslator(self.trans) 
             # 3


if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = Demo()
    demo.show()
    sys.exit(app.exec_())

Любая помощь будет оценена.

Ответы [ 2 ]

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

TL;DR; Нет необходимости использовать Qt Designer


Вы не должны обязательно использовать Qt Designer, но вы должны использовать ту же технику, то есть создать метод, который можно было бы назвать retranslateUi()и в нем установите тексты, используя translate() вместо tr() (для более подробной информации читайте документы ).Вызов этого метода при изменении языка для него должен использовать событие changeEvent().Например, в вашем случае код выглядит следующим образом:

import sys
from PyQt5 import QtCore, QtGui, QtWidgets

class Demo(QtWidgets.QWidget):
    def __init__(self):
        super(Demo, self).__init__()
        self.button = QtWidgets.QPushButton()
        self.label = QtWidgets.QLabel(alignment=QtCore.Qt.AlignCenter)

        self.combo = QtWidgets.QComboBox(self)
        self.combo.currentIndexChanged.connect(self.change_func)

        self.trans = QtCore.QTranslator(self)

        self.v_layout = QtWidgets.QVBoxLayout(self)
        self.v_layout.addWidget(self.combo)
        self.v_layout.addWidget(self.button)
        self.v_layout.addWidget(self.label)

        options = ([('English', ''), ('français', 'eng-fr' ), ('中文', 'eng-chs'), ])

        for i, (text, lang) in enumerate(options):
            self.combo.addItem(text)
            self.combo.setItemData(i, lang)
        self.retranslateUi()

    @QtCore.pyqtSlot(int)
    def change_func(self, index):
        data = self.combo.itemData(index)
        if data:
            self.trans.load(data)
            QtWidgets.QApplication.instance().installTranslator(self.trans)
        else:
            QtWidgets.QApplication.instance().removeTranslator(self.trans)

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

    def retranslateUi(self):
        self.button.setText(QtWidgets.QApplication.translate('Demo', 'Start'))
        self.label.setText(QtWidgets.QApplication.translate('Demo', 'Hello, World'))

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    demo = Demo()
    demo.show()
    sys.exit(app.exec_())

Затем сгенерируйте .ts:

pylupdate5 main.py  -ts eng-chs.ts
pylupdate5 main.py  -ts eng-fr.ts

Затем используйте Qt Linguist для выполнения переводов.

И, наконец, .qm:

lrelease eng-fr.ts eng-chs.ts

enter image description here

enter image description here

enter image description here

Полный проект вы найдете здесь .

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

Нет, вам придется использовать технику, которую Qt Designer использует с retranslateUi, потому что система виджетов Qt не может самостоятельно переделать перевод (в противном случае QT Designer использовал бы это для).

Построение такой системы потребовало бы фундаментальных изменений в виджетах, поскольку для каждого свойства строки вам необходимо знать, что оно содержит переводимую строку (не значение данных), и знание исходной строки для поиска нового перевода будет лучший (обратные переводы могут быть неоднозначными).

...