How to force QLocale::system to change
Asked Answered
S

3

4

I need to test my application translation to non-English language very often, and this is very uncomfortable to change the whole operating system language just to do this simple check. How can i change Qt-detected system language using environment variables for example? or with command-line parameter.

I try to change LANG, LANGUAGE environment variables, but it has no effect. However, under GNOME it has!

UPD: code i'm using such code to determine the system locale and load appropriate translation:

QTranslator app_translator;
if (!app_translator.load ("app_" + QLocale::system ().name (), app_tr_dir))
    qWarning ("Can't load app translator file for locale %s from %s", qPrintable (QLocale::system ().name ()), app_tr_dir.toLocal8Bit().data());
else
    app.installTranslator (&app_translator);

P.S. My OS is Kubuntu 13.10, Qt version is 4.8.

Snowshoe answered 28/1, 2014 at 13:50 Comment(0)
C
2

For testing you can use something like that (just correct main function):

int main(int argc, char **argv) {
    QApplication app(argc, argv);

    QLocale localeUsedToDeterminateTranslators = QLocale::system();
    Q_FOREACH(QString a, app.arguments()) {
        const static localeParam = "-locale:";
        if (a.startsWith(localeParam)) {
           localeUsedToDeterminateTranslators = QLocale(a.mid(sizeof(localeParam)-1));
           break;
        }
    }
    ... // your normal code

Then when you run you app you can just run it with extra parameter: ./yourAppName -locale:nl. See documentation of QLocale for possible values.


Edit: I've found even better approach, there is a method QLocale::setDefault, so this should work even better:
int main(int argc, char **argv) {
    QApplication app(argc, argv);

    Q_FOREACH(QString a, app.arguments()) {
        const static localeParam = "-locale:";
        if (a.startsWith(localeParam)) {
           QLocale::setDefault(QLocale(a.mid(sizeof(localeParam)-1)));
           break;
        }
    }
    ...
    QTranslator app_translator;
    if (!app_translator.load ("app_" + QLocale().name (), app_tr_dir))
         qWarning ("Can't load app translator file for locale %s from %s", qPrintable (QLocale().name()), app_tr_dir.toLocal8Bit().data());
    else
         app.installTranslator (&app_translator);
Corrosive answered 28/1, 2014 at 18:18 Comment(3)
So, your advice is just use custom command line parameter? Ok, that can helps. But i'm just curious - how do the QLocale::system determine the currenly selected locale. It's better to understood this than create appropriate QLocale object by brute force :)Snowshoe
somewhere in your code you should use locale to determinate which translations to load. In your code you have QLocale::system ().name () so you just replace that with localeUsedToDeterminateTranslators.name().Corrosive
Under Gnome QLocale::system understood LANG env variable changing, so looks like it is KDE bug/feature. Thanks, i'll mark your answer as a solution of my problem.Snowshoe
H
4

You can always change the locale by QLocale::setDefault() method. here's an example from one project:

void Language::setCurrentLanguage(Language::Languages language)
{
    if (language == Language::Arabic) {
        QLocale l(QLocale::Arabic, QLocale::SaudiArabia);
        QLocale::setDefault(l);
        dynamic_cast<MangoApp*>(qApp)->setLayoutDirection(Qt::RightToLeft);
        dynamic_cast<MangoApp*>(qApp)->removeAllTranslator();
        dynamic_cast<MangoApp*>(qApp)->loadQtTranslator();
        dynamic_cast<MangoApp*>(qApp)->loadMangoTranslator();

    } else {
        QLocale l(QLocale::English, QLocale::UnitedStates);
        QLocale::setDefault(l);
        dynamic_cast<MangoApp*>(qApp)->setLayoutDirection(Qt::LeftToRight);
        dynamic_cast<MangoApp*>(qApp)->removeAllTranslator();
    }
}
Hal answered 28/1, 2014 at 14:0 Comment(3)
Thanks, but i want something else - to change language at runtime without special code writing. Using for example environment variable. Qt has a way to determine the current system language. I just want to deceive it :)Snowshoe
On my windows machine I add an environment variable LANG=ar_SA.UTF8 and it work for designer.exe. On Linux you can try to run the app like this: LANG=en_US.UTF8 app_name. Another solution is add your own command line and parse it when the application start.Hal
I.e. you application is successfully change its language by changing LANG env variable? I'm trying to change it, but with no effect. If so, looks like the problem is in my app ;(Snowshoe
C
2

For testing you can use something like that (just correct main function):

int main(int argc, char **argv) {
    QApplication app(argc, argv);

    QLocale localeUsedToDeterminateTranslators = QLocale::system();
    Q_FOREACH(QString a, app.arguments()) {
        const static localeParam = "-locale:";
        if (a.startsWith(localeParam)) {
           localeUsedToDeterminateTranslators = QLocale(a.mid(sizeof(localeParam)-1));
           break;
        }
    }
    ... // your normal code

Then when you run you app you can just run it with extra parameter: ./yourAppName -locale:nl. See documentation of QLocale for possible values.


Edit: I've found even better approach, there is a method QLocale::setDefault, so this should work even better:
int main(int argc, char **argv) {
    QApplication app(argc, argv);

    Q_FOREACH(QString a, app.arguments()) {
        const static localeParam = "-locale:";
        if (a.startsWith(localeParam)) {
           QLocale::setDefault(QLocale(a.mid(sizeof(localeParam)-1)));
           break;
        }
    }
    ...
    QTranslator app_translator;
    if (!app_translator.load ("app_" + QLocale().name (), app_tr_dir))
         qWarning ("Can't load app translator file for locale %s from %s", qPrintable (QLocale().name()), app_tr_dir.toLocal8Bit().data());
    else
         app.installTranslator (&app_translator);
Corrosive answered 28/1, 2014 at 18:18 Comment(3)
So, your advice is just use custom command line parameter? Ok, that can helps. But i'm just curious - how do the QLocale::system determine the currenly selected locale. It's better to understood this than create appropriate QLocale object by brute force :)Snowshoe
somewhere in your code you should use locale to determinate which translations to load. In your code you have QLocale::system ().name () so you just replace that with localeUsedToDeterminateTranslators.name().Corrosive
Under Gnome QLocale::system understood LANG env variable changing, so looks like it is KDE bug/feature. Thanks, i'll mark your answer as a solution of my problem.Snowshoe
E
0

Using the LANGUAGE (not LANG) environment variable should definitely change the value returned by QLocale::system().name(), because this environment variable has precedence over all other ways to define the application message locale (details).

I tested it this with Qt 5.12 under Lubuntu 19.10 (means, using the LXQt desktop), and it works. The command was:

LANGUAGE=de ./application

If this really does not work under Kubuntu, it should be reported as a bug, because then Kubuntu is interfering with the way how an application is told its locale.

Euterpe answered 26/7, 2020 at 17:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.