简体   繁体   中英

QLocale detects system language incorrectly on Windows with language pack installed

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?

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区域和语言格式设置(德语)

Hope that helps.

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);

我有同样的问题,我解决了这个代码。

QString local =  QLocale::languageToString(QLocale::system().language());

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM