3

I am attempting to detect current system language with QLocale:

QLocale::Language sysLangId = QLocale::system().language();

However, it's not working correctly. I'm on Russian Windows 7 with English language pack applied, but language() returns Russian instead of English. Is there any workaround?

Violet Giraffe
  • 32,368
  • 48
  • 194
  • 335

4 Answers4

6

When I was working on Localization in Qt, I used

QString locale = QLocale::system().name();

When I tested getting the locale, I found it was dependent on the Format in the Region and Language settings:

Control Panel > Region and Language > Format

Windows Region and Language Format Setting (german)

Hope that helps.

phyatt
  • 18,472
  • 5
  • 61
  • 80
  • Understood. Indeed, that's exactly what QLocale::system() indicates, and it makes sense now that I think about it. But how can I detect system UI language? – Violet Giraffe Sep 04 '13 at 06:08
  • It is probably one of the other settings in Region and Language, like the Location, or the Keyboard, or the Administrative > Language for non-Unicode programs. (I would try the last one first). – phyatt Sep 04 '13 at 06:22
2

I've found 2 ways to solve my problem. The Qt way is to use QLocale::system().uiLanguages(). On my system it returns a list with a single item "en-US". The problem with that is I need a language name, like "english", so I'd have to add a map for converting language code to language name. It's no big deal, but I've decided to use WinAPI:

QString sysLangName;
const LANGID langId = GetUserDefaultUILanguage();
WCHAR langName[1000] = {0};
if (GetLocaleInfoW(MAKELCID(langId, SORT_DEFAULT), LOCALE_SENGLANGUAGE, langName, sizeof langName / sizeof langName[0] - 1) != 0)
    sysLangName = QString::fromWcharArray(langName);
Violet Giraffe
  • 32,368
  • 48
  • 194
  • 335
  • Is there any WinAPI to give codes like en_US instead of full language name? I am reluctant to use `QLocale::system().uiLanguages()`, as its documentation says that it returns a list of locale names and in that list, the first item is the most preferred one. This preferred one may not be the current ui language (not sure). – user2653062 May 26 '15 at 12:32
2

I had the same problem and I solved with this code.

QString local =  QLocale::languageToString(QLocale::system().language());
Leonardo Alves Machado
  • 2,747
  • 10
  • 38
  • 53
1

To get the language name you can simply use QLocale::languageToString(QLocale::system().language()); or maybe QLocale::system().nativeLanguageName(); but the real problem is as you mentioned that the QLocale::system() does not always match the actual system locale on windows. This can be observed if you change the locale during program execution. In this case the QLocale::system() does not get up-to-date and returns the old value. Here is a workaround I used in Qt5:

class WinEventFilter : public QAbstractNativeEventFilter
{
public:     
    bool nativeEventFilter(const QByteArray &eventType, void *message, long *result)
    {
        if (((MSG*)message)->message == WM_WININICHANGE )
        {
            // Workaround - in Qt5 the system locale is not up to date and we have to manually update it.
#ifdef _DEBUG
            QLibrary lib("Qt5Cored.dll");
#else
            QLibrary lib("Qt5Core.dll");
#endif
            void (* func)() = lib.resolve("?updateSystemPrivate@QLocalePrivate@@SAXXZ");
            if (func)
                func();
            else
                qDebug()<<"! Unable to resolve updateSystemPrivate()";
            // Workaround end

            qDebug()<<"WM_WININICHANGE"<<QLocale::languageToString(QLocale::system().language());
        }

        return false;
    }    
};

and my application class constructor looks like this:

MyApplication::MyApplication( int & argc, char ** argv ) 
: QApplication(argc, argv)
{
    WinEventFilter *pFilter = new WinEventFilter(this);
    installNativeEventFilter(m_pEventFilter);
}

Hope this helps.

Uga Buga
  • 1,724
  • 3
  • 19
  • 38