Добавление и локализация пунктов меню в главном меню панели приложений Qt

Итак, прежде всего вот скриншот упомянутого меню Evernote, локализованного на французском языке:

[введите описание изображения здесь]

Как вы можете видеть, все пункты меню в главном меню (под главным меню я имею в виду тот, чье имя является именем приложения, как здесь Evernote) локализованы по-французски. Есть много пунктов меню, которые приносит само приложение Evernote, например Evaluez Evernote для Mac (Оцените Evernote для Mac), Информация du compte … (Информация об аккаунте…) и т. д. Кроме того, есть стандартные OS X пункты меню, такие как Выйти из Evernote, предпочтения, и т.д., которые также локализованы.

Мои вопросы:

  1. Как добавить новый пункт в это главное меню? Как получить доступ к этому меню, чтобы добавить элементы?
  2. Как мне локализовать эти элементы в зависимости от локализации моего приложения, как в OS X, так и в тех, которые я добавил по умолчанию?
  3. В меню 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)));
}

3

Решение

Может быть, вы могли бы переопределить в 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 :("));
}
}

Я надеюсь, что это помогает.

4

Другие решения

Я до сих пор не нашел полного ответа на свои проблемы. Но вот некоторые из наблюдений, которые я сделал за последние несколько дней:

  1. Чтобы иметь возможность добавлять пункты меню в главное меню, вы должны соответствующим образом установить роль меню, то есть, добавив ее куда угодно (это не имеет значения, потому что она будет перемещаться), вы устанавливаете роль меню следующим образом. :

    fYourAction->setMenuRole(QAction::ApplicationSpecificRole);
    

Это добавит пункт меню в главное меню. Если вы добавите таким образом больше, чем элемент, они будут отображаться в том порядке, в котором вы устанавливаете их роли в меню.

  1. Есть несколько конкретных ролей, которые Qt уже предоставляет — то есть для About <app> вещь, Quit <app> вещь, Preferences... пункт и т. д. Они упоминаются Вот.
    Например, если у вашего действия есть текст «Foo», и вы добавляете его где-то в качестве пункта меню, и устанавливаете роль как

    fFooAction->setMenuRole(QAction:: PreferencesRole);
    

затем он автоматически перейдет в главное меню и покажет как Preferences..., какой текст вы на самом деле поместите в действие, будет несущественным. Какой бы слот вы ни прикрепили к нему в ответ на triggered() сигнал все равно будет срабатывать корректно. То же самое касается QAction::AboutRole кроме того, какой бы текст вы ни добавили в этом действии, он переместится в главное меню и отобразится как About <your_app_name>.

  1. Проблема с QAction::AboutRole или же QAction:: PreferencesRole как я уже сказал, они не локализуются, даже если вы попробуете. Они будут локализованы только при изменении языкового стандарта системы. Если вы измените его только в своем приложении, установив новый переводчик, он не изменится. Обходной путь? Избегайте их и используйте QAction::ApplicationSpecificRole для всех пунктов, которые вы хотите появиться в главном меню. Затем они будут должным образом локализованы в соответствии с вашим пользовательским переводчиком и будут уважать любой текст, который вы предоставите в действии, т.е. если вы дадите Foo как текст в действии, он будет выглядеть как Foo в главном меню, и соответственно локализуйтесь. Опять же, учтите, что при добавлении нескольких элементов установите роль элементов в порядке их появления, т. Е. Чтобы смоделировать меню Evernote выше, сначала установите роль меню для about_app действие, то preferences действие. То, где вы их добавляете, не будет иметь значения, поскольку они будут перемещены в новое меню, поэтому порядок, в котором вы устанавливаете роль меню для элементов, будет определять порядок их появления в главном меню.

  2. Проблема с вышеупомянутым подходом состоит в том, что я не знаю, как вставить разделители между элементами, которые я добавляю в главном меню. Это легко сделать в меню, которое мы добавляем, поскольку у нас есть доступ к объекту меню, но здесь у нас нет доступа (мы добавляем элементы куда-то еще и перемещаем их в главное меню, устанавливая роль меню ), поэтому я пока не знаю, как добавить несколько разделителей в главном меню.

3

По вопросам рекламы [email protected]