#python #qml #translation #pyside2
Вопрос:
Я знаю процесс перевода строк в QML. Но есть ли способ полностью перевести свойства QML с помощью функций QML? Я работаю с PySide2, и мне нужно будет перевести свойства, определенные на стороне Python и QML. В качестве минималистичного примера пока без функций перевода:
main. py
class example_model(QObject):
def __init__(self, parent=None):
super().__init__(parent=parent)
self._model = QStandardItemModel()
@Property(str, constant=True)
def python_property(self):
return "Example String"
def main():
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
context = engine.rootContext()
model = example_model( parent=context)
context.setContextProperty("exampleModel", model)
engine.load(QUrl(QUrl.fromLocalFile(os.path.join(os.path.dirname(inspect.getfile(lambda: None)), "main.qml"))))
return app.exec_()
if __name__ == '__main__':
sys.exit(main())
main.qml
import QtQuick 2.12
import QtQuick.Controls 2.12
ApplicationWindow {
id: root
width: 200
height: 400
visible: true
property string qmlProperty: "exampleString"
Text{
text: QT_TR_NOOP(exampleModel.python_property)
}
Text{
text: QT_TR_NOOP(root.qmlProperty)
}
}
Как я могу добиться того, чтобы эти два свойства ( python_property
и qmlProperty
) были правильно обнаружены функцией Qt lupdate или любой другой функцией соответственно. Мне нужен динамический перевод, поэтому engine.retranslate()
функция будет использоваться.
Комментарии:
1. Во-первых,
QT_TR_NOOP
это, как следует из названия, не-операция, поэтому то, как вы ее здесь используете, ничего не даст. Вы должны разместить его повсюду"exampleString"
, чтобы люпдейт обнаружил его. И я думаю , что вы можете завершить свой квест, поставивqsTr
вместо двух привязокQT_TR_NOOP
, но не на 100% уверены в этом. Стоит отметить, что lupdate ставитmain.qml
в качестве контекста, поэтому вам следует позаботиться о том, гдеQT_TR_NOOP
иqsTr
используются
Ответ №1:
Перевод похож на QML только тем, что для использования перевода python вам необходимо использовать qsTranslate, где вы должны передать контекст (имя класса python), поскольку он отличается от контекста qml (имя класса .файл qml).
С другой стороны, кажется, что OP не понимает работу QT_TR_NOOP, поэтому рекомендуется просмотреть документы.
Используя следующий пример, я покажу процесс перевода:
import os
import sys
from pathlib import Path
from PySide2.QtCore import (
Property,
QCoreApplication,
QObject,
Qt,
QTimer,
QTranslator,
QUrl,
)
from PySide2.QtGui import QGuiApplication
from PySide2.QtQml import QQmlApplicationEngine
CURRENT_DIRECTORY = Path(__file__).resolve().parent
QML_DIRECTORY = CURRENT_DIRECTORY / "qml"
TRANSLATIONS_DIR = CURRENT_DIRECTORY / "translations"
class PythonModel(QObject):
def python_property(self):
return self.tr("Python Example String")
pythonProperty = Property(str, fget=python_property, constant=True)
def main():
app = QGuiApplication(sys.argv)
py_tranlator = QTranslator()
res = py_tranlator.load(os.fspath(TRANSLATIONS_DIR / "py.qm"))
assert res
qml_tranlator = QTranslator()
res = qml_tranlator.load(os.fspath(TRANSLATIONS_DIR / "qml.qm"))
assert res
python_model = PythonModel(app)
engine = QQmlApplicationEngine()
engine.rootContext().setContextProperty("pythonModel", python_model)
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)
ok = False
def handle_timeout():
nonlocal ok
if ok:
QCoreApplication.installTranslator(py_tranlator)
QCoreApplication.installTranslator(qml_tranlator)
else:
QCoreApplication.removeTranslator(py_tranlator)
QCoreApplication.removeTranslator(qml_tranlator)
engine.retranslate()
ok = not ok
timer = QTimer(interval=1000, timeout=handle_timeout)
timer.start()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
import QtQuick 2.12
import QtQuick.Controls 2.12
ApplicationWindow {
id: root
property string qmlProperty: qsTr("QML Example String")
width: 200
height: 400
visible: true
Column {
Text {
text: qsTranslate("pythonModel", pythonModel.pythonProperty)
}
Text {
text: root.qmlProperty
}
}
}
├── main.py
├── qml
│ └── main.qml
└── translations
├── py.qm
├── py.ts
├── qml.qm
└── qml.ts
- Создайте .ts с помощью pyside2-lupdate и lupdate:
pyside2-lupdate main.py -ts translations/py.ts lupdate qml/main.qml -ts translations/qml.ts
- Добавьте переводы с помощью инструмента Qt Linguist.
- Сгенерируйте .qm с использованием lrelease:
lrelease translations/py.ts translations/py.qm lrelease translations/qml.ts translations/qml.qm
- Затем вам нужно загрузить оба перевода.
Если вы не хотите иметь несколько .ts или .qm, вы можете использовать lconvert для объединения файлов.
Полный пример вы можете найти здесь.