3

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

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

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

你有什么想法可以帮助我吗?

谢谢你的回答。

盖特

4

1 回答 1

5

当您在应用程序中添加翻译时,qApp->installTranslator(& aTranslator)所有以下对(和类似函数)的调用QObject::tr()都将在翻译器中查找已翻译文本。所以你应该调用retranslateUi() after 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()ui 中的每个用户可见字符串。它在结束时自动调用,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.
}
于 2012-07-23T14:49:33.927 回答