[Interest] Dynamic translations for mobile apps at runtime?

André Somers andre at familiesomers.nl
Wed Mar 9 08:24:49 CET 2016



Op 08/03/2016 om 23:21 schreef Jason H:
> Sounds like there should be a qApp->translations() that we can use to remove all currently installed translations? Without it, we have to do what you do.
Just keep the translators you currently have active around, not all of 
them. It is useless to new a QTranslator for languages you are not 
actually using. When switching language, you can remove and then delete 
the already loaded ones after installing the translations for the newly 
selected language.

So, something like this (untested code, typed in email editor):

QString m_currentLanguage;
QVector<QTranslator*> m_currentTranslations; //note that for any language, you may need multiple translation files!

void Backend::selectLanguage( QString language ) {
   if (language == m_currentLanguage)
     return;

   QVector oldTranslators = m_currentTranslations;
   m_currentTranslations.clear();

   //repeat for every translation file you need to install, ie for your own app, for Qt itself, for libraries...
   translator = new QTranslator(this);
   translator->load( language, commonPath()+"/translations" );
   qApp->installTranslator(translator);
   m_currentTranslations.append(translator);

   //now, get rid of the old translators
   foreach(QTranslator* oldTranslator, oldTranslators) {
     qApp->removeTranslator(oldTranslator);
     delete oldTranslator;
   }
}



André

>
>
>> Sent: Tuesday, March 08, 2016 at 3:44 PM
>> From: Gianluca <gmaxera at gmail.com>
>> To: "Jason H" <jhihn at gmx.com>
>> Cc: "interest at qt-project.org" <interest at qt-project.org>
>> Subject: Re: [Interest] Dynamic translations for mobile apps at runtime?
>>
>> qApp->installTranslator add a new translation into the stack. Does not remove the old ones.
>> So, if the user click 10 times: Italian - English - Italian - English … etc…
>> you got ten translator into the memory.
>> That’s because the translation is searched into the order on which the translator are installed into the stack.
>>
>> That’s why I remove everything so there is only one translators at time into the memory.
>>
>> Il giorno 08/mar/2016, alle ore 18:46, Jason H <jhihn at gmx.com> ha scritto:
>>
>>> I'm wondering why you load all those languages and then remove all but one of them? Being a mobile app, I have to be somewhat conscience of memory foot print. Do you see anything wrong with:
>>>
>>> void Backend::selectLanguage( QString language ) {
>>>     translator = new QTranslator(this);
>>>     translator->load( language, commonPath()+"/translations" );
>>>     qApp->installTranslator(translator);
>>> }
>>>
>>> ?
>>>
>>>
>>>> Hello Jason,
>>>> I got the same issue some times ago … and I found that it’s possible to use the translation feature of Qt … that seems static, but it’s not.
>>>> And localize.biz it’s a wonderful site that allow you to modify Qt translation files directly on web and download the updated one.
>>>>
>>>> The trick to achieve (summarized) is the following:
>>>> Somewhere in your code maintain and update from remote an array of Translators:
>>>> 	translators["en"] = new QTranslator(this);
>>>> 	translators["en"]->load( "tr_en", commonPath()+"/translations" );
>>>> 	translators["de"] = new QTranslator(this);
>>>> 	translators["de"]->load( "tr_de", commonPath()+"/translations" );
>>>> 	translators["fr"] = new QTranslator(this);
>>>> 	translators["fr"]->load( "tr_fr", commonPath()+"/translations" );
>>>> 	translators["ru"] = new QTranslator(this);
>>>> 	translators["ru"]->load( "tr_ru", commonPath()+"/translations" );
>>>> You can change these entry with new files downloaded at runtime.
>>>>
>>>> Then you implement a method that you call at runtime for changing the translator, something like that:
>>>>
>>>> void Backend::selectLanguage( QString language ) {
>>>> 	foreach( QString lang, translators.keys() ) {
>>>> 		if ( lang == language ) {
>>>> 			qApp->installTranslator( translators[lang] );
>>>> 		} else {
>>>> 			qApp->removeTranslator( translators[lang] );
>>>> 		}
>>>> 	}
>>>> 	this->language = language;
>>>> 	emit languageChanged();
>>>> }
>>>> And then there is the final trick:
>>>> You create a “fake” property that is always an empty string but it’s binded to languageChanged signal:
>>>>
>>>> Q_PROPERTY( QString es READ getES NOTIFY languageChanged )
>>>>
>>>> And (the most annoying part), append this empty string to all string you want to change at runtime like that:
>>>>
>>>> qsTr("NEWS<br/>HUB")+backend.es
>>>>
>>>> And close the loop.
>>>>
>>>> What will happen is the following: the translator change at runtime and you trigger a languageChanged that trigger an update of all string that got backend.es appended that trigger the call of qsTr that take the new translation from the new translator.
>>>>
>>
> _______________________________________________
> Interest mailing list
> Interest at qt-project.org
> http://lists.qt-project.org/mailman/listinfo/interest




More information about the Interest mailing list