Как переводить строки, добавленные динамически в Qapp с Qtranslator?

Я пытался создать многоязычное приложение Qt с помощью лингвиста Qt. Я помещаю этот код в функцию моего главного окна:

translator.load(":/lang/English");
qApp->installTranslator(&translator);
ui->retranslateUi(this);

С QTranslator объявить в моем MainWindow.h и все мои строки, которые я хочу перевести, заключить в tr() . Но при этом все QObject, динамически добавленные кодом моего MainWindow.cpp, например заголовок QTableWidget, не переводятся. Если я помещаю другой переводчик в мой main.cpp, все мои строки переводятся, но я должен создать языковую кнопку в своем приложении, и поэтому я не могу поместить переводчик в main.cpp.

У вас есть идея, чтобы помочь мне?

Спасибо за ваши ответы.

фарватер

1 ответ

Решение

Когда вы добавляете перевод в свое приложение, используя qApp->installTranslator(& aTranslator) затем все последующие вызовы QObject::tr() (и аналогичные функции) будет искать в переводчике переведенный текст. Так что вы должны позвонить retranslateUi() после qApp->installTranslator(), На самом деле вы можете не назвать это там, вы можете переопределить QWidget::changeEvent() и перехватить любой QEvent::LanguageChange событие.

void MainWindow::changeEvent(QEvent *e)
{
    QMainWindow::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        // Someone called qApp->installTranslator() with a new translation.
        // Let's update the user visible strings.

        // This function was created by uic from the Designer form.
        // It translates all user visible texts in the form.
        ui->retranslateUi(this);

        // This function must be written by you. It translates other user visible
        // texts that are not in the form. See down for an example.
        this->retranslateUi();
        break;
    default:
        break;
    }
}

ui->retranslateUi() просто звонки QObject::tr() для каждого пользователя видимая строка в пользовательском интерфейсе. Он вызывается автоматически в конце setupUi() и заполняет виджеты формы переведенным текстом (посмотрите, он определен в ui_MainWindow.h файл). Возможно, вы захотите использовать аналогичный подход с другими видимыми пользователем текстами, такими как заголовок QTableWidget. Все строки установлены в функции (возможно, названной retranslateUi() для согласованности), который вызывается при запуске приложения (или, что лучше, после создания соответствующих виджетов) и каждый раз при загрузке новых переводов.

MainWindow::MainWindow(QWidget * parent)
  : QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // Creates other widgets, but do not set their user visible texts.
    tableWidget = new QTableWidget(this);
    ...
    someControl = new QLineEdit(this);
    someOtherControl = new QSpinBox(this);

    someModel = new MyModel(this);
    ...


    // Ok, *now* we set their texts.
    this->retranslateUi();
}

...

void MainWindow::retranslateUi()
{
    // This function will be called (either manually or automatically by
    // `changeEvent()`) when a new translator has installed, hence all the `tr()`
    // calls will return the right translation for the last installed language.

    QStringList labels;
    labels.append(tr("First column"));
    labels.append(tr("Second column"));
    labels.append(tr("Third column"));

    tableWidget->setHorizontalHeaderLabels(labels);

    someControl->setText(tr("Control name"));
    someOtherControl->setText(tr("Other control name"));

    // Perhaps you have a model that need to be retranslated too
    // (you need to write its `retranslateUi()` function):
    someModel->retranslateUi();

    ...
}

Также обратите внимание, что если вы делаете что-то вроде

void MainWindow::someFunction()
{
    ...

    QTranslator translator;
    translator.load(":/lang/English");
    qApp->installTranslator(& translator);

    ...
}

как только эта функция вернет переменную translator разрушается, поэтому в следующий раз QObject::tr() называется адрес, сохраненный с qApp->installTranslator(& translator) будет недействительным. Так что вы должны выделить translator в кучу с new (и, возможно, удалив его delete когда тебе это больше не нужно). Исключением является то, что если вы делаете это в main() перед звонком QCoreApplication::exec() так как эта функция блокирует и не вернется, пока приложение не будет закрыто.

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

    ...

    QTranslator translator;
    translator.load(":/lang/English");
    app.installTranslator(& translator);

    ...

    app.exec(); // This function will return only on application's exit.
                // Hence `translator` will outlive the application, there is
                // no need to worry about it.
}
Другие вопросы по тегам