URL: https://www.opennet.ru/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 10294
[ Назад ]

Исходное сообщение
"Не работает перевод до старта QApplication. Как обойти?"

Отправлено xintrea , 20-Янв-20 09:54 
Перед тем, как будет стартовать объект 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



Содержание

Сообщения в этом обсуждении
"Не работает перевод до старта QApplication. Как обойти?"
Отправлено Аноним , 20-Янв-20 14:30 
> Перед тем, как будет стартовать объект QApplication (метод exec()), мне нужно подготовить
> определенные файлы, которые нужны для корректного старта, чтобы приложение могло их
> найти.

...
*ля,
не приходило на ум - что скорее всего система сигнал-слот не будет работать до запуска exec() ?

>> Или, может быть, есть какой-то другой метод?

Дффух - фазoвая инициализация ?
Пример, ah( simple win-helper ), в конструкторе ph, вызов void init(); где происходит подготовка всех кишок аппы:

int main(
int argc,
char *argv[])
{

  int ret = 0;

  FMemWatcher memWatcher;

  FAppHelper ah;
  if (!ah.isOk()) {

    ret = -1;
    }

  // make copy because qt may change
  FArg arg(argc,argv);
  if (!arg.isOk()) {

    ret = -2;
    }

  if (0 == ret) {

    FGuiApplication app(argc, argv);
    FPluginHolder ph(arg, &memWatcher);

    if (ph.isOk()) {

      ret = app.exec();
      }
    else {

      ret = -3;
      }
    }

  memWatcher.Dump();

  return ret;

};


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

Имо, там перекроить вопрос 30-90 минут...

P.S.:
Вроде как еще на gamedev, не отметились.. :)