QLocale неправильно определяет язык системы в Windows с установленным языковым пакетом

Я пытаюсь определить текущий язык системы с QLocale:

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

Тем не менее, это не работает правильно. Я на русском Windows 7 с пакетом английского языка применяется, но language() возвращает русский вместо английского. Есть ли обходной путь?

4 ответа

Решение

Я нашел 2 способа решить мою проблему. Путь Qt заключается в использовании QLocale::system().uiLanguages(), В моей системе он возвращает список с одним элементом "en-US". Проблема в том, что мне нужно название языка, например "английский", поэтому мне нужно добавить карту для преобразования кода языка в название языка. Ничего страшного, но я решил использовать 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);

Когда я работал над локализацией в Qt, я использовал

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

Когда я тестировал получение локали, я обнаружил, что это зависит от настроек Формат в регионе и Язык:

Панель управления> Регион и язык> Формат

Регион Windows и настройка формата языка (немецкий

Надеюсь, это поможет.

У меня была такая же проблема, и я решил с этим кодом.

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

Чтобы получить название языка, вы можете просто использовать QLocale::languageToString(QLocale::system().language()); или, может быть QLocale::system().nativeLanguageName(); но реальная проблема заключается в том, что вы упомянули, что QLocale::system() не всегда совпадает с реальным языковым стандартом системы в Windows. Это можно наблюдать, если вы измените локаль во время выполнения программы. В этом случае QLocale::system() не обновляется и возвращает старое значение. Вот обходной путь, который я использовал в 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;
    }    
};

и мой конструктор класса приложения выглядит так:

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

Надеюсь это поможет.

Другие вопросы по тегам