是否可以动态翻译QT应用程序而无需复制代码



我在项目中集成了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/international.html#dynamic-translation)

对于使用QT设计师编写的应用程序,似乎只能致电

ui->retranslateUi(this);

changeEvent()函数中,所有文本字段都将被翻译。但是对于应用程序中的所有其他文本,必须如上示例设置文本。我发现很痛苦,因为当我更改某些内容时,我总是需要在两个地方更新文本(在changeEvent功能和程序的主要部分中)。在许多文本字段中,很容易错过任何东西。

是否有一种方法可以更新这些文本字段,而无需复制"文本设定方法"?

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

主要想法是在changeEvent()处理程序中设置可翻译的文本,并按照文档中所述手动发送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();
}

在一般情况下,不,您无法避免。

一个选项是而不是让应用程序代码直接设置文本,而是将信号连接到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);
    }
}

最新更新