Смена языка интерфейса в программе "на лету"

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Аватара пользователя
vitaly_l
долгожитель
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41
Контактная информация:

Сообщение vitaly_l »

Лекс Айрин писал(а):А у меня не требовало... что я делаю не так?

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

Ichthyander - спасибо, про i18/


.
Аватара пользователя
Лекс Айрин
долгожитель
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград
Контактная информация:

Сообщение Лекс Айрин »

vitaly_l, а что тут приводить... я их обновляю на лету.
heX
новенький
Сообщения: 12
Зарегистрирован: 19.02.2016 16:20:32

Сообщение heX »

В процессе тестирования на отдельной программе выяснилось следующее:

Модуль DefaultTranslator нужен только чтобы при старте программы автоматически произвести ее перевод.
Этот модуль просто вызывает функцию SetDefaultLang и больше ничего не делает и ни на что не влияет.

Если вы хотите больше контроля над локализацией то подключайте модуль LCLTranslator и вызывайте функцию SetDefaultLang сами.
При вызове с соответствующим параметром она переводит всю программу на требуемый язык без перезапуска ("на лету").

В процессе тестирования выяснилось:
TAction работает совершенно корректно - если вы назначаете кнопкам Action то их изначальный текст удаляется из файла перевода.
И остается только один экземпляр текста - от TAction.
Вызов функции SetDefaultLang переводит все компоненты (включая TAction).

Выделять строки в resourcestring не нужно, в этом нет никакого смысла - локализация TAcionList выполняет этот функционал лучше, удобнее, проще и автоматически. (Почему так делают в examples? - видимо examples устарели и в те времена таким подходом решали какойто баг)

Но! Если TAcionList лежит в TDataModule, то для корректного перевода нужно вызывать SetDefaultLang уже после создания всех форм, но до их появления на экране (иначе все TAction не будут переведены).
При повторном запуске SetDefaultLang (уже после создания) перевод применяется на все кроме TAcionList который лежит в TDataModule (и компонент связанных с ним).
Также сложилось впечатление что сам LazarusIDE немного неправильно обрабатывает TAcionList который лежит в TDataModule и из-за этого в '*.po' файлах происходит дублирование.
Итог - TAcionList нужно просто хранить в TForm.

P.S. В багтрекере этот баг не искал - может он известен давно. Все описанное актуально для Lazarus 1.4 и Typhon 5.5.

Добавлено спустя 45 минут 34 секунды:
vitaly_l писал(а):Я делал через SessionProperties и сохранял всё в ini

Жуть какая! Не делайте так больше, пользуйтесь l18i (пример ищите здесь: \lazarus\examples\translation).
Последний раз редактировалось heX 25.02.2016 17:05:25, всего редактировалось 3 раза.
Аватара пользователя
Лекс Айрин
долгожитель
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград
Контактная информация:

Сообщение Лекс Айрин »

heX писал(а):Жуть какая! Не делайте так больше, пользуйтесь l18i


Лично ВЫ привели развернутый аргумент против этого.

Вообще, я делал так... в ini проставляется только язык программы. А уже внутри программы вызывается процедура смены, если надо, языка. Конечно, для расширения списка языков придется потрудиться, но это не такая уж неподъемная задача.

ЗЫ: потом, правда, я вообще выпилил многоязычную поддержку. Но все работало на лету.
heX
новенький
Сообщения: 12
Зарегистрирован: 19.02.2016 16:20:32

Сообщение heX »

Лекс Айрин писал(а):
heX писал(а):ЗЫ: потом, правда, я вообще выпилил многоязычную поддержку. Но все работало на лету.

Ну у меня теперь тоже все работает на лету (поменял TDataModule в TForm).
Но я еще и кода не писал ни строчки - единственная строка в проекте это SetDefaultLang(). :D
Аватара пользователя
Лекс Айрин
долгожитель
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград
Контактная информация:

Сообщение Лекс Айрин »

heX, у меня программа для личного пользования, так что пока поддержка нескольких языков это уже мания величия.
Аватара пользователя
Ichthyander
энтузиаст
Сообщения: 701
Зарегистрирован: 04.04.2007 08:32:43
Откуда: Астрахань
Контактная информация:

Сообщение Ichthyander »

heX писал(а):В процессе тестирования на отдельной программе выяснилось следующее:

Модуль DefaultTranslator нужен только чтобы при старте программы автоматически произвести ее перевод.
Этот модуль просто вызывает функцию SetDefaultLang и больше ничего не делает и ни на что не влияет.

Если вы хотите больше контроля над локализацией то подключайте модуль LCLTranslator и вызывается функцию SetDefaultLang сами.
При вызове с соответствующим параметром она переводит всю программу на требуемый язык без перезапуска ("на лету").

В процессе тестирования выяснилось:
TAction работает совершенно корректно - если вы назначаете кнопкам Action то их изначальный текст удаляется из файла перевода.
И остается только один экземпляр текста - от TAction.
Вызов функции SetDefaultLang переводит все компоненты (включая TAction).

Выделять строки в resourcestring не нужно, в этом нет никакого смысла - локализация TAcionList выполняет этот функционал лучше, удобнее, проще и автоматически. (Почему так делают в examples? - видимо examples устарели и в те времена таким подходом решали какойто баг)

Но! Если TAcionList лежит в TDataModule, то для корректного перевода нужно вызывать SetDefaultLang уже после создания всех форм, но до их появления на экране (иначе все TAction не будут переведены).
При повторном запуске SetDefaultLang (уже после создания) перевод применяется на все кроме TAcionList который лежит в TDataModule (и компонент связанных с ним).
Также сложилось впечатление что сам LazarusIDE немного неправильно обрабатывает TAcionList который лежит в TDataModule и из-за этого в '*.po' файлах происходит дублирование.
Итог - TAcionList нужно просто хранить в TForm.

Спасибо, надо будет попробовать. Как бы решил это все без использования переключения языков на лету. Просто в редких случаях, когда это действительно нужно предложил запускать программу с ключами -lang ru для выбора языка принудительно. Один раз задал и пользуйся, если автоматиечески выбранный язык не устраивает. Но, тем не менее, я конечно попробую снова добавить эту фичу, просто это пока далеко не первоочередная задача. Вопрос: все текстовые свойства (caption, hint и т.д.) компонентов (кнопки, диалоги, label и прочее) также переводятся на лету?

Добавлено спустя 2 минуты 28 секунд:
vitaly_l писал(а):
Лекс Айрин писал(а):А у меня не требовало... что я делаю не так?

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

Нет, он использует свой велосипед, то есть нештатные средства.
Ichthyander - спасибо, про i18/.

Не за что. Рекомендую: один раз разберетесь, потом пойдет все как по маслу. Предоставьте заботу о поддержке локализации самой среде Lazarus. Там еще масса удобств с этим i18n
Аватара пользователя
Лекс Айрин
долгожитель
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград
Контактная информация:

Сообщение Лекс Айрин »

Ichthyander писал(а):он использует свой велосипед,


Имхо, лучше велосипед, чем штатный костыль.
Аватара пользователя
Ichthyander
энтузиаст
Сообщения: 701
Зарегистрирован: 04.04.2007 08:32:43
Откуда: Астрахань
Контактная информация:

Сообщение Ichthyander »

Лекс Айрин писал(а):
Ichthyander писал(а):он использует свой велосипед,


Имхо, лучше велосипед, чем штатный костыль.


Не хотелось бы вступать в дискуссию, но... Просто вот мой опыт от использования i18n:
избавило меня от кучи рукописного кода, (то есть практически никакого кода!),
предоставил мне удобные фичи, встроенные от Lazarus,
смог воспользоваться готовыми внешними инструментами (к примеру, программа POEdit для переводчиков). Я спокойно отдал файлы .po на перевод непрограммисту и кинул ссылку на программу. Я же сосредоточился на программировании, а не заботами о локализации программы.
открытый формат файлов локализации.
Ну это так навскидку. Я понимаю, что в небольших программах, особенно, если не сталкивался еще с i18n можно самому написать код. Но на будущее лучше изучить это и использовать во всех своих проектах. Это мое мнение, что это возможность, которая упрощает жизнь программисту, почему не использовать!? дискутировать нет смысла, каждый из нас уже понял друг друга.
Аватара пользователя
Лекс Айрин
долгожитель
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград
Контактная информация:

Сообщение Лекс Айрин »

Ichthyander, если правильно подойти к построению велосипеда, то половину из этого можно спокойно реализовать даже проще, например, обеспечить перевод хоть через яндекс-переводчик в автоматическом режиме. Проблема в том, что штатное решение и есть костыль. Для полноценной мультиязычности надо соответствующим образом строить программы.... выносить, как минимум, строковые ресурсы в набор переменных и вручную менять язык.

i18n хорош для тех, кто уже написал программу и не хочет ее переписывать заново.

Ichthyander писал(а):это возможность, которая упрощает жизнь программисту, почему не использовать!?


например, чтобы иметь больший контроль над программой. Реализацию i18n могут внезапно поменять... или выпилить, заменив другой технологией. А за лисапед я спокоен.
heX
новенький
Сообщения: 12
Зарегистрирован: 19.02.2016 16:20:32

Сообщение heX »

Ichthyander писал(а):Вопрос: все текстовые свойства (caption, hint и т.д.) компонентов (кнопки, диалоги, label и прочее) также переводятся на лету?

Да, все свойства типа TTranslateString (caption, hint, text) у всех компонент обрабатываются.
Но все свойства типа TStrings не попадают (например содержимое TMemo) - их нужно делать через stringresurces.
Аватара пользователя
vitaly_l
долгожитель
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41
Контактная информация:

Сообщение vitaly_l »

heX писал(а):Жуть какая! Не делайте так больше, пользуйтесь l18i; для корректного перевода нужно вызывать SetDefaultLang уже после создания всех форм

Вовсе и не жуть :oops: :cry: :arrow: всё прекрасно работает.
Но в будущем я естественно буду пользоваться i18n. Я не знал о существовании i18n. :evil:
Лекс Айрин писал(а):перевод хоть через яндекс-переводчик в автоматическом режиме

Идея мне понравилась, Вам <= респект! Вот бы ещё кто, нить модуль такой для Lazarus сделал (модификацию i18n). :wink:


.
heX
новенький
Сообщения: 12
Зарегистрирован: 19.02.2016 16:20:32

Сообщение heX »

В тему локализации еще могу посоветовать сайт https://poeditor.com/ (я перерыл почти 10 подобных проектов - этот самый лучший).
Перевод упрощается еще сильнее. Просто загружаете туда сформированный файл языка - и пользователи программы могут потом сами присоединятся к переводу, добавлять языки, и совместно переводить. А вам остается только выгружать готовые переводы и следить за актуальностью базовой версии "терминов".
Плюс можно привязывать файлы к github репозиторию - очень упрощается выгрузка и загрузка.

Например у меня недавно два китайца молча подсоединились и за пару дней перевели всю программу на китайский, итого уже пять языков :P
Аватара пользователя
Лекс Айрин
долгожитель
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград
Контактная информация:

Сообщение Лекс Айрин »

vitaly_l писал(а):Вот бы ещё кто, нить модуль такой для Lazarus сделал (модификацию i18n).


зачем? Загоняешь PO файл в переводчик и на его основе делаешь перевод. Да и сам перевод строк через онлайн переводчик не проблема.
Ответить