LINUX.ORG.RU

процесс перевода Qt5-приложения на другой язык

 ,


0

2

Встала необходимость перевести некоторую программу на английский язык для иностранного пользователя. Сделал маленькую кошечную программу для тренировки на оной.

Похоже, я не совсем понимаю принцип процесса перевода в рамках Qt5, документация его не сильно проясняет. Как я понимаю процесс:

1) Тексты виджетов в ui (у меня чисто Widgets-based) сами найдутся, а в коде обрамляем нужные строки при помощи tr.

2) lupdate найдет все такие строки, до кучи к элементам интерфейса, и сформирует ts-файл. А где с этим файлом дальше работать? В каком ПО? Пока вижу лишь консольные lupdate и lrelease.

3) Создаю копии этого ts-файла: mytr_ru.ts и mytr_en.ts и затем перевожу строки в en файле, используя простой текстовый редактор. Мне кажется ЯДЧНТ.

4) Далее пытаюсь обработать при помощи lrelease, но оно жалуется что перевод не закончен и создает почти пустой qm-файл.

Далее понятно, если у меня будет нормальный qm-файл, я его загружу либо из каталога, либо из ресурсов (если получится) при помощи QTranslator::load.

Пробовал курить https://habrahabr.ru/post/51319/ и http://doc.qt.io/qt-5/internationalization.html - пока не торкнуло понимание.

А где с этим файлом дальше работать? В каком ПО?

linguist, идет в комплекте с Qt

annulen ★★★★★
()

3) Создаю копии этого ts-файла: mytr_ru.ts и mytr_en.ts и затем перевожу строки в en файле, используя простой текстовый редактор. Мне кажется ЯДЧНТ.

открой, файл сделанный lupdate в linguist и переведи там, если хочешь это делать без linguist, посмотри diff и меняй файл также как linguist.

на полученный файл направливаешь lrelease - получаешь qm.

dhampire ★★★
()
  1. Оформляешь вывод в tr();
  2. lupdate;
  3. Переводишь в Qt Linguist;
  4. Используешь QTranslator;
  5. Заново устанавливаешь тот же текст через tr().

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

XMs ★★★★★
()
Последнее исправление: XMs (всего исправлений: 2)

Правильнее, ИМХО, вывод делать сразу через tr() и на английском. А дальше, в зависимости от установленной локали (QLocale в помощь), подгружать нужный перевод, если таковой имеется. Если же нужного перевода нет, то использовать английский.
И, как уже советовали, перевод нужно делать с помощью Qt Linguist.

baldman88
()

ТС когда устанешь понимать, приходи ко мне на консультацию.

MikeDM ★★★★★
()
Ответ на: комментарий от RazrFalcon

Не очень понял, как одно с другим связано. Под «держать статичный вывод в одной функции» имелись ввиду всякие setText(), setTitle() и прочее для членов класса. Откуда эта функция будет дёргаться, в общем-то, не важно

XMs ★★★★★
()
Ответ на: комментарий от XMs

Это стандартная связка для смены языка не лету. Я хз о чём писали вы и что там сделано в KDE, но в Qt уже есть механизм для этого.

RazrFalcon ★★★★★
()
Ответ на: комментарий от RazrFalcon

Попробую иначе. Как происходит динамическое обновление перевода?

  1. Происходит событие;
  2. Выполняется установка текста.

Первое может быть чем угодно — от события QEvent::LanguageChanged до получения QDialog::Accepted от диалога смены языка интерфейса, например:

QTranslator translator;
...
LanguageSelectionDialog dialog;
...
if (dialog.exec() == QDialog::Accepted
 && translator.load(dialog.pathToTranslation()))
  {
	Elm1.setTitle(tr(...));
	Elm2.setTitle(tr(...));
	...
	label1.setText(tr(...));
	label2.setText(tr(...));
	...
  }
Второе — это ряд вызовов setText(), setTitle() и им подобных. Вот это всё я и предлагал вынести в отдельную функцию (как, к слову, делает Qt Designer)

XMs ★★★★★
()
Ответ на: комментарий от RazrFalcon

Кстати, тем, у кого до сих пор сорцы на русском, но есть желание исправиться, рискну порекламировать мой велосипед.

hobbit ★★★★★
()
Ответ на: комментарий от dhampire

XMs baldman88 MikeDM RazrFalcon

Сделал, я допер как перевести этот ts файл, скомпилировал в qm, загрузил - перевод работает, хорошо.

Когда я делаю модификации программы, меняю строки на языке оригинала в коде программы - как мне потом обновить этот ts файл? Выхлоп lupdate --help не дает подсказку. Когда я делаю lupdate -ts мой_файл.ts то он удаляет все ссылки на то в каком месте программы эти строки находятся и в результате перевод не работает.

Не понятно как обновлять уже существующий перевод, как создать новый с нуля - ясно.

I-Love-Microsoft ★★★★★
() автор топика
Ответ на: комментарий от I-Love-Microsoft

Когда я делаю lupdate -ts мой_файл.ts то он удаляет все ссылки на то в каком месте программы эти строки находятся и в результате перевод не работает

Ну да, я в таких случаях просто заново делаю перевод изменённой строки. Хотя иногда этого делать не приходится, уж не знаю, с чем это связано

XMs ★★★★★
()
Ответ на: комментарий от XMs

Так у меня весь файл ts ломается... Пропадает location. Но ведь я правильно вызываю lupdate? Так же как в первый раз надо?

 <context>
     <name>gui</name>
     <message>
-        <location filename="gui.ui" line="14"/>
         <source>gui</source>
-        <translation>Translation</translation>
+        <translation type="vanished">Translation</translation>
     </message>
     <message>
-        <location filename="gui.ui" line="21"/>
         <source>текст на форме приложения</source>
-        <translation>text on the form</translation>
+        <translation type="vanished">text on the form</translation>
     </message>
     <message>
-        <location filename="gui.cpp" line="9"/>
         <source>текст в коде программы</source>
-        <translation>text in the source code</translation>
+        <translation type="vanished">text in the source code</translation>
     </message>
 </context>
 </TS>

Когда первый раз вызываю - он создает ts-файл. Когда второй - результат выше.

I-Love-Microsoft ★★★★★
() автор топика
Ответ на: комментарий от I-Love-Microsoft

Но ведь я правильно вызываю lupdate?

Вроде бы да (по крайней мере не увидел каких-либо ключей, которые бы я использовал). Если честно, никогда не смотрел внутрь ts-файла, ограничиваясь связкой lupdate+Qt Linguist

XMs ★★★★★
()
Ответ на: комментарий от I-Love-Microsoft

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

Измененные значения, то есть те, которых уже нет, ведь они были изменены на другие, помечаются как vanished и тега location у них нет. Не переведенные помечаются как unfinished. Ну а переведенные никак не помечаются. Как-то так:

Завершенный перевод:
<name>MainWindow</name>
<message>
    <location filename="MainWindow.ui" line="14"/>
    <source>MainWindow</source>
    <translation>Главное окно</translation>
</message>

Незавершенный перевод:
<name>MainWindow</name>
<message>
    <location filename="MainWindow.ui" line="14"/>
    <source>MainWindow</source>
    <translation type="unfinished"></translation>
</message>

Удаленный перевод:
<name>MainWindow</name>
<message>
    <source>MainWindow</source>
    <translation type="vanished">Главное окно</translation>
</message>
В Вашем случае есть только одно логическое объяснение — форма (gui.ui) со всеми элементами была удалена.

baldman88
()
Ответ на: комментарий от I-Love-Microsoft

Пропадает location

Он вообще-то не нужен. Используется только для отображения нужной строки в лингвисте.

RazrFalcon ★★★★★
()
Ответ на: комментарий от RazrFalcon

Всем спасибо за помощь! Приложение уже успешно переведено! И lupdate корректно работает когда разобрался.

I-Love-Microsoft ★★★★★
() автор топика

XMs baldman88 MikeDM RazrFalcon

Странная проблема: translator.load - true, a.installTranslator - true. Но перевод не применяется. По каким причинам такое может быть?

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

Непонятно, ведь загружается и применяется. Указывать какой язык/локаль ведь не надо, раз я гружу translator.load тот или иной файл - значит там уже нужный мне язык.

I-Love-Microsoft ★★★★★
() автор топика
Ответ на: комментарий от I-Love-Microsoft

Текст (тот, который в tr()) нужно устанавливать после загрузки перевода. Или и до, и после, в зависимости от того, как планируется работа с локализацией.


Потом прочитал что перед установкой перевода не должны появляться виджеты

Не знаю, где ты это прочитал, но ни о чём подобном я не слышал. В моих проектах в начале устанавливается английский текст, а потом, если есть переводы, заменяется локализацией, при том это может делать сам пользователь, когда, собственно, виджеты и всё остальное создано и показано

XMs ★★★★★
()
Ответ на: комментарий от XMs

Ну и вообще, покажи код, где QTranslator и где tr(), а ещё в какой последовательности они идут

XMs ★★★★★
()
Ответ на: комментарий от MikeDM

XMs Елки иголки, укуси меня пчела, вот в чем была ошибка:

Так работает:

en1ru0 = true;
	QTranslator translator;
	qDebug() << "en1ru0=" << en1ru0;
	if(en1ru0)
	{
		bool tr = translator.load
А так уже нет:
en1ru0 = true;
	qDebug() << "en1ru0=" << en1ru0;
	if(en1ru0)
	{
		QTranslator translator;
		bool tr = translator.load
Чтоб я сдох, ни за что бы не догадался что в этом проблема...

Неужели оно уничтожало translator после выхода из if???

I-Love-Microsoft ★★★★★
() автор топика
Последнее исправление: I-Love-Microsoft (всего исправлений: 1)
Ответ на: комментарий от I-Love-Microsoft

Неужели оно уничтожало translator после выхода из if???

Эм… Разумеется, локальные переменные/экземпляры классов уничтожаются по выходу из их области видимости. Насколько мне известно, это справедливо для всех C-подобных языков.

Экземпляр QTranslator, IMHO, лучше держать где-нибудь в main или в классе главного окна

XMs ★★★★★
()
Ответ на: комментарий от XMs

Я на самом деле понимаю что объект уничтожается, просто я не увидел где написано что он должен оставаться. А так, он пропадает и не пишет ошибку в консоль, типа был переводчик а его на бочку с порохом посадили.

I-Love-Microsoft ★★★★★
() автор топика
Ответ на: комментарий от I-Love-Microsoft

просто я не увидел где написано что он должен оставаться.

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

XMs ★★★★★
()
Ответ на: комментарий от I-Love-Microsoft

Неужели оно уничтожало translator после выхода из if???

тут должна быть нереально большая гифка с фейспалмом.

что бы этого не было, делай динамически его. А еще лучше прочти офф документацию по трансляции. там в примерах есть все.

MikeDM ★★★★★
()
Ответ на: комментарий от baldman88

Отвратительный подход. Никогда не думали, что фраза на английском может переводиться двумя разными значениями в зависимости от контекста?

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.