Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Не работает перевод интерфейса до старта QApplication. Можно это как-то обойти?



  • Перед тем, как будет стартовать объект QApplication (метод exec()), мне нужно подготовить определенные файлы, которые нужны для корректного старта, чтобы приложение могло их найти.

    Подготовка файлов требует пользовательского выбора с вопросом "где разместить нужные файлы?". Соответственно нужно открыть окно, в котором будет интерфейс выбора. Окно такое есть, оно унаследовано от QDialog, оно работает даже до запуска основного приложения.

    Но вот проблема: в этом окне есть код автоматического определения языка системы. И он работает, и он определяет язык, и устанавливает его приложению, и этот код запускается самым первым в конструкторе окна:

    // Автоматическое определение языка системы
    void InstallDialog::setupAutoLangTranslation()
    {
        QString lang=QLocale().system().name().split('_').first().toLower();
        QStringList availableLang={"en", "ru"};
    
        if( !availableLang.contains(lang) )
            lang="en";
    
        qDebug() << "Auto detect lang in installator: " << lang;
    
        // Подключение перевода интерфейса
        QString langFileName=":/resource/translations/mytetra_"+lang+".qm";
        qDebug() << "Lang file: " << langFileName;
    
        QTranslator langTranslator;
        bool loadResult=langTranslator.load(langFileName);
    
        if(loadResult)
        {
            qDebug() << "Success load translation file";
            qApp->installTranslator(&langTranslator); // Транслятор устанавливается в объекте приложения
        }
        else
            qDebug() << "Can't load translation file";
    }
    

    Все установки строк в классе этого окна происходят после данного кода. Естественно, все строки обернуты в tr(), сделаны lupdate, linguist, lrelease.

    Однако перевода интерфейса не происходит.

    Я думал, что перевод не работает из-за того, что настройка языка делается в конструкторе окна. Однако, внутри класса окна есть вызов еще одного диалогового окна QMessageBox, создаваемом на месте вызова на стеке:

    void InstallDialog::onAccepted()
    {
        if( !ui->m_radioButtonStandart->isChecked() and
            !ui->m_radioButtonPortable->isChecked() )
        {
            QMessageBox msgBox;
            msgBox.setText(tr("Please select one of install mode."));
            msgBox.exec();
        }
        else
        {
            this->accept();
        }
    }
    

    И в этом окне тоже перевод не работает.

    Я сейчас грешу только на то, что перевод не работает из-за того, что объект приложения создан, но его основной цикл не запущен. А применение перевода сделано где-то в глубинах запуска основного цикла.

    Вопрос в том, можно ли как-то выйти из этой проблемы, и заставить работать систему локализации Qt? Может быть, есть какой-то вызов, который обновит систему локализации без запуска основного цикла приложения? Или, может быть, есть какой-то другой метод?

    Очень не хотелось бы в корне переделывать все приложение из-за такой вот особенности Qt.

    Исходники: https://github.com/xintrea/mytetra_dev

    Места в исходниках:

    • /app/src/views/installDialog/InstallDialog.h
    • /app/src/views/installDialog/InstallDialog.cpp
    • /app/src/libraries/GlobalParameters.cpp, метод initWorkDirectory()
    • /app/src/main.cpp, функция main(), вызов globalParameters.init();

    Примечание: Чтобы появилось проблемное окно, не должно существовать директории ~/.config/mytetra



  • В общем, ларчик просто открывался: QTranslator устанавливался в QApplication через installTranslator(), но сразу же удалялся при выходе из метода setupAutoLangTranslation(), потому что лежал на стеке.

    Достаточно QTranslator сделать как свойство диалога InstallDialog, чтобы он существовал все время работы окна, и перевод начинает работать.


Log in to reply