我知道有几乎相同的问题张贴在本地化在QtQuick从上到下,但那里的家伙已经知道如何开始,进一步的它是基于c++。
在我的问题中,我还必须实时翻译QML端上的所有字符串,但后端使用Python (PySide)而不是c++。由于我是本节的新手,我不知道如何用最少的Python实现这一点。
基于链接的问题,我到目前为止能够:
- 将QT_TR_NOOP()添加到所有可翻译字符串中,以便在运行时进行翻译。
但我不清楚那里描述的进一步步骤。Python的QML文档非常简洁。
如果能提供一些详细的描述或例子,我将非常感谢。
逻辑类似于c++中所做的,因为QML不改变任何东西,您只需要适应python中的逻辑。
步骤如下:
-
使用lupdate从qml生成。ts .
lupdate main.qml -ts i18n_es.ts
-
使用Qt Linguist添加翻译
-
使用lrelease编译。ts到。qm。
lrelease i18n_es.ts i18n_es.qm
-
使用python加载。qm .
├── main.py
├── qml
│ └── main.qml
└── translations
├── i18n_es.qm
├── i18n_es.ts
├── i18n_fr.qm
└── i18n_fr.ts
main.py
import os
import re
import sys
from pathlib import Path
from PySide2.QtCore import (
Property,
QCoreApplication,
QDir,
QObject,
Qt,
QTranslator,
QUrl,
Signal,
Slot,
)
from PySide2.QtGui import QGuiApplication, QStandardItem, QStandardItemModel
from PySide2.QtQml import QQmlApplicationEngine
CURRENT_DIRECTORY = Path(__file__).resolve().parent
QML_DIRECTORY = CURRENT_DIRECTORY / "qml"
TRANSLATIONS_DIR = CURRENT_DIRECTORY / "translations"
class Translator(QObject):
language_changed = Signal(name="languageChanged")
def __init__(self, engine, parent=None):
super().__init__(parent)
self._engine = engine
self._languages_model = QStandardItemModel()
self.load_translations()
self._translator = QTranslator()
@Slot(str)
def set_language(self, language):
if language != "Default":
trans_dir = QDir(os.fspath(TRANSLATIONS_DIR))
filename = trans_dir.filePath(f"i18n_{language}.qm")
if not self._translator.load(filename):
print("Failed")
QGuiApplication.installTranslator(self._translator)
else:
QGuiApplication.removeTranslator(self._translator)
self._engine.retranslate()
def languages_model(self):
return self._languages_model
languages = Property(QObject, fget=languages_model, constant=True)
def load_translations(self):
self._languages_model.clear()
item = QStandardItem("Default")
self._languages_model.appendRow(item)
trans_dir = QDir(os.fspath(TRANSLATIONS_DIR))
for filename in trans_dir.entryList(["*.qm"], QDir.Files, QDir.Name):
language = re.search(r"i18n_(.*?).qm", filename).group(1)
item = QStandardItem(language)
self._languages_model.appendRow(item)
def main():
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
translator = Translator(engine, app)
engine.rootContext().setContextProperty("translator", translator)
filename = os.fspath(QML_DIRECTORY / "main.qml")
url = QUrl.fromLocalFile(filename)
def handle_object_created(obj, obj_url):
if obj is None and url == obj_url:
QCoreApplication.exit(-1)
engine.objectCreated.connect(handle_object_created, Qt.QueuedConnection)
engine.load(url)
sys.exit(app.exec_())
if __name__ == "__main__":
main()
main.qml
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
ApplicationWindow {
width: 640
height: 480
visible: true
title: qsTr("Title")
ListModel {
id: list_model
ListElement {
name: QT_TR_NOOP("house")
}
ListElement {
name: QT_TR_NOOP("table")
}
ListElement {
name: QT_TR_NOOP("chair")
}
}
ColumnLayout {
anchors.fill: parent
ComboBox {
model: translator ? translator.languages : null
textRole: "display"
Layout.fillWidth: true
onActivated: function(index) {
translator.set_language(currentText);
}
}
Button {
text: qsTr("name")
Layout.fillWidth: true
}
ListView {
model: list_model
Layout.fillWidth: true
Layout.fillHeight: true
delegate: Text {
text: qsTr(name)
}
}
}
}
完整的例子在这里