Я интегрировал 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 designer, кажется, что можно просто вызвать
ui->retranslateUi(this);
в пределах changeEvent()
функция и все текстовые поля будут переведены.
Но для всех других текстов в приложении текст должен быть установлен как в примере выше. Что мне больно, потому что мне всегда нужно обновлять текст в двух местах, когда я что-то меняю (в changeEvent
функция и в основной части моей программы).
С большим количеством текстовых полей может легко что-то пропустить.
Есть ли способ обновить эти текстовые поля без необходимости дублировать «text-setting-method»?
Я не уверен, зачем вам нужно дублировать текстовые сеттеры.
Основная идея состоит в том, чтобы установить переводимые тексты один раз в 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();
}
В общем случае нет, вы не можете избежать этого.
Один вариант — вместо того, чтобы код приложения непосредственно устанавливал текст, подключите сигнал к лямбда-выражению, устанавливающему текст, а затем запустите сигнал. Затем обработчик событий просто должен запустить сигнал.
Пример:
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);
}
}