如何翻译使用Qtranslator在App中动态添加的字符串?

时间:2012-07-23 08:25:48

标签: qt qtablewidget qtranslate

我试图用Qt语言学家创建一个Qt应用程序多语言。 我将此代码放在我的MainWindow函数中:

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

QTranslator在我的MainWindow.h中声明,我想要的所有字符串都由tr()括起来。但是,通过我的MainWindow.cpp的代码添加动态的所有QObject,例如QTableWidget的标题,都没有被翻译。 如果我在main.cpp中放置了另一个翻译器,我的所有字符串都是翻译的,但我必须在我的应用程序中创建语言按钮,所以我不能将翻译器放在main.cpp中。

你有想法帮助我吗?

谢谢你的答案。

Gat的

1 个答案:

答案 0 :(得分:5)

当您使用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()只需为ui中的每个用户可见字符串调用QObject::tr()即可。它在setupUi()的末尾自动调用,并使用已翻译的文本填充表单的小部件(看看,它由ui_MainWindow.h文件中的uic定义)。您可能希望采用与其他用户可见文本类似的方法,例如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.
}