Итак, прежде всего вот скриншот упомянутого меню Evernote, локализованного на французском языке:
[]Как вы можете видеть, все пункты меню в главном меню (под главным меню я имею в виду тот, чье имя является именем приложения, как здесь Evernote) локализованы по-французски. Есть много пунктов меню, которые приносит само приложение Evernote, например Evaluez Evernote для Mac (Оцените Evernote для Mac), Информация du compte … (Информация об аккаунте…) и т. д. Кроме того, есть стандартные OS X пункты меню, такие как Выйти из Evernote, предпочтения, и т.д., которые также локализованы.
Мои вопросы:
Что я пробовал:
fMenuBar = fMainWindow->menuBar();
fMenuFile = fMenuBar->addMenu(QObject::tr(qPrintable(String_Class::FileMenu))); //"File" in English, translated into other languages
fAboutAppAct = new QAction(QObject::tr(qPrintable(String_Class::About_App)), fMainWindow); //prints "About App", localized in all languages
fMenuFile->addAction(fAboutAppAct);
fAboutAppAct->setMenuRole(QAction::AboutRole); //otherwise it sits with the other file menu options in the File menu
//reset UI language slot, called whenver UI language is reset. It retranslates all strings in all menus, except this
void AppMenu::reTranslateUISlot()
{
fAboutAppAct->setText(QObject::tr(qPrintable(String_Class::About_App)));
}
Может быть, вы могли бы переопределить в MainWindow
или в AppMenu
changeEvent
,
void MainWindow::changeEvent(QEvent *event)
{
if (event->type() == QEvent::LanguageChange) {
this->retranslateUi(this);
quickStart->retranslateUi(quickStart);
//etc...
} else {
QMainWindow::changeEvent(event);
}
}
Вы могли бы заставить виджеты перевести себя. Но сначала вам нужно зарегистрировать какой-нибудь QTranslator.
Например, в конструкторе MainWindow (или в некотором диалоговом окне конфигурации), если возможно изменить язык во время выполнения (что я сделал в моем программном обеспечении):
CustomizeOptionsDialog::CustomizeOptionsDialog(QWidget *parent)
: QDialog(parent, Qt::Tool)
{
// Load the language of the application
customTranslator.load(languages.value( SettingsPrivate::instance()->language()) );
// Translate standard buttons (OK, Cancel, ...)
defaultQtTranslator.load("qt_" + SettingsPrivate::instance()->language(), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
QApplication::installTranslator(&customTranslator);
QApplication::installTranslator(&defaultQtTranslator);
}
Где language () возвращает «fr», «gb» или «cs» (инициализируется из сигнала, испускаемого при выборе нового языка в опциях).
/** Change language at runtime. */
void CustomizeOptionsDialog::changeLanguage(const QString &language)
{
QString lang = languages.value(language);
SettingsPrivate *settings = SettingsPrivate::instance();
// If the language is successfully loaded, tells every widget that they need to be redisplayed
if (!lang.isEmpty() && lang != settings->language() && customTranslator.load(lang)) {
settings->setLanguage(language);
defaultQtTranslator.load("qt_" + lang, QLibraryInfo::location(QLibraryInfo::TranslationsPath));
QApplication::installTranslator(&customTranslator);
/// TODO: reload plugin UI
QApplication::installTranslator(&defaultQtTranslator);
} else {
labelStatusLanguage->setText(tr("No translation is available for this language :("));
}
}
Я надеюсь, что это помогает.
Я до сих пор не нашел полного ответа на свои проблемы. Но вот некоторые из наблюдений, которые я сделал за последние несколько дней:
Чтобы иметь возможность добавлять пункты меню в главное меню, вы должны соответствующим образом установить роль меню, то есть, добавив ее куда угодно (это не имеет значения, потому что она будет перемещаться), вы устанавливаете роль меню следующим образом. :
fYourAction->setMenuRole(QAction::ApplicationSpecificRole);
Это добавит пункт меню в главное меню. Если вы добавите таким образом больше, чем элемент, они будут отображаться в том порядке, в котором вы устанавливаете их роли в меню.
Есть несколько конкретных ролей, которые Qt уже предоставляет — то есть для About <app>
вещь, Quit <app>
вещь, Preferences...
пункт и т. д. Они упоминаются Вот.
Например, если у вашего действия есть текст «Foo», и вы добавляете его где-то в качестве пункта меню, и устанавливаете роль как
fFooAction->setMenuRole(QAction:: PreferencesRole);
затем он автоматически перейдет в главное меню и покажет как Preferences...
, какой текст вы на самом деле поместите в действие, будет несущественным. Какой бы слот вы ни прикрепили к нему в ответ на triggered()
сигнал все равно будет срабатывать корректно. То же самое касается QAction::AboutRole
кроме того, какой бы текст вы ни добавили в этом действии, он переместится в главное меню и отобразится как About <your_app_name>
.
Проблема с QAction::AboutRole
или же QAction:: PreferencesRole
как я уже сказал, они не локализуются, даже если вы попробуете. Они будут локализованы только при изменении языкового стандарта системы. Если вы измените его только в своем приложении, установив новый переводчик, он не изменится. Обходной путь? Избегайте их и используйте QAction::ApplicationSpecificRole
для всех пунктов, которые вы хотите появиться в главном меню. Затем они будут должным образом локализованы в соответствии с вашим пользовательским переводчиком и будут уважать любой текст, который вы предоставите в действии, т.е. если вы дадите Foo как текст в действии, он будет выглядеть как Foo в главном меню, и соответственно локализуйтесь. Опять же, учтите, что при добавлении нескольких элементов установите роль элементов в порядке их появления, т. Е. Чтобы смоделировать меню Evernote выше, сначала установите роль меню для about_app
действие, то preferences
действие. То, где вы их добавляете, не будет иметь значения, поскольку они будут перемещены в новое меню, поэтому порядок, в котором вы устанавливаете роль меню для элементов, будет определять порядок их появления в главном меню.
Проблема с вышеупомянутым подходом состоит в том, что я не знаю, как вставить разделители между элементами, которые я добавляю в главном меню. Это легко сделать в меню, которое мы добавляем, поскольку у нас есть доступ к объекту меню, но здесь у нас нет доступа (мы добавляем элементы куда-то еще и перемещаем их в главное меню, устанавливая роль меню ), поэтому я пока не знаю, как добавить несколько разделителей в главном меню.