是否可以在没有代码重复的情况下动态翻译Qt应用程序?

时间:2017-03-14 13:56:15

标签: c++ qt qtranslate

我在项目中集成了QTranslator类。到目前为止一切正常,并且在重新启动程序时,所有文本字段都被翻译。现在我想提供动态翻译,因此用户无需重新启动应用程序。

我在研究中发现,必须重新实现changeEvent()这样的功能:

void MyWidget::changeEvent(QEvent *event)
{
    if (event->type() == QEvent::LanguageChange) {
        titleLabel->setText(tr("Document Title"));
        ...
        okPushButton->setText(tr("&OK"));
    } else
        QWidget::changeEvent(event);
}

(资料来源:http://doc.qt.io/qt-5/internationalization.html#dynamic-translation

对于使用Qt设计器编写的应用程序,似乎可以只调用

ui->retranslateUi(this);
changeEvent()函数中

将翻译所有文本字段。 但是对于应用程序中的所有其他文本,必须按照上面的示例设置文本。我觉得很痛苦,因为我总是需要在我改变某些东西时更新两个地方的文本(在changeEvent函数和程序的主要部分)。 有很多文本字段很容易错过一些东西。

有没有办法更新这些文本字段而无需复制“text-setting-methods”?

2 个答案:

答案 0 :(得分:2)

我不确定你为什么需要复制文本设置器。

主要想法是在changeEvent()处理程序中设置可翻译文本一次,并按send中的说明手动docs LanguageChange事件。这也将触发子窗口小部件的事件。

MyWidget::MyWidget(QWidget *parent) : QWidget(parent)
{
    titleLabel = new QLabel(this);
    okPushButton = new QPushButton(this);
    // Fire the LanguageChange event - the event handler will set the texts:
    QEvent languageChangeEvent(QEvent::LanguageChange);
    QCoreApplication::sendEvent(this, &languageChangeEvent);
}

void MyWidget::changeEvent(QEvent *event)
{
    if (event->type() == QEvent::LanguageChange) {
        titleLabel->setText(tr("Document Title"));
        okPushButton->setText(tr("&OK"));
    } else {
        QWidget::changeEvent(event);
    }
}

您还可以使用一些初始QCoreApplication::installTranslator()。这将触发LanguageChange事件,无需手动发布。

另一种方法是使用您自己的函数而不是事件。这种方法通常是相同的,除了你需要手动为子窗口小部件调用你的函数。

MyWidget::MyWidget(QWidget *parent) : QWidget(parent)
{
    titleLabel = new QLabel(this);
    okPushButton = new QPushButton(this);
    myChildWidget = new MyChildWidget(this);
    retranslate();
}

void MyWidget::retranslate()
{
    titleLabel->setText(tr("Document Title"));
    okPushButton->setText(tr("&OK"));
    myChildWidget->retranslate();
}

答案 1 :(得分:1)

在一般情况下,不,你不能避免这种情况。

一个选项是让应用程序代码直接设置文本,将信号连接到设置文本的lambda,然后触发信号。然后事件处理程序也需要触发信号。

一个例子:

MyWidget::someCalculation() {
    // Some stuff
    disconnect(this, &MyWidget::updateText, button, Q_NULLPTR);
    connect(this, &MyWidget::updateText, button, [someLocalString](){ button->setText(tr("Button Text %1").arg(someLocalString)); });
    // More stuff
    emit updateText();
}

// Other methods

void MyWidget::changeEvent(QEvent *event)
{
    if (event->type() == QEvent::LanguageChange) {
        emit updateText();
    } else {
        QWidget::changeEvent(event);
    }
}