Как переводить строки, добавленные динамически в Qapp с Qtranslator?
Я пытался создать многоязычное приложение Qt с помощью лингвиста Qt. Я помещаю этот код в функцию моего главного окна:
translator.load(":/lang/English");
qApp->installTranslator(&translator);
ui->retranslateUi(this);
С QTranslator объявить в моем MainWindow.h и все мои строки, которые я хочу перевести, заключить в tr() . Но при этом все QObject, динамически добавленные кодом моего MainWindow.cpp, например заголовок QTableWidget, не переводятся. Если я помещаю другой переводчик в мой main.cpp, все мои строки переводятся, но я должен создать языковую кнопку в своем приложении, и поэтому я не могу поместить переводчик в main.cpp.
У вас есть идея, чтобы помочь мне?
Спасибо за ваши ответы.
фарватер
1 ответ
Когда вы добавляете перевод в свое приложение, используя 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()
просто звонки QObject::tr()
для каждого пользователя видимая строка в пользовательском интерфейсе. Он вызывается автоматически в конце setupUi()
и заполняет виджеты формы переведенным текстом (посмотрите, он определен в ui_MainWindow.h
файл). Возможно, вы захотите использовать аналогичный подход с другими видимыми пользователем текстами, такими как заголовок 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.
}