Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding and localizing menu items in the main menu of a Qt application menubar

So first of all here is a screenshot of the said menu of Evernote, localized in French:

[enter image description here]

As you can see, all the menu items in the main menu (by main menu I mean the one whose name is the application name, like here it is Evernote) are localized in French. There are lots of menu items which the Evernote app itself brings, like Évaluez Evernote pour Mac (Rate Evernote for Mac), Information du compte... (Account Info...), etc. Plus there are the standard OS X provided menu items like Quit Evernote, Preferences, etc which are also localized.

My questions:

  1. How do I add a new item in this main menu? How to access this menu to add items?
  2. How do I localize these items based on my app localization, both OS X provided default ones and the ones I add?
  3. In the Evernote menu, everything seems to be localized except the Services menu option (the submenu options are however localized!)? Can't this be localized as well?

What I have tried:

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))); 
}
like image 451
SexyBeast Avatar asked Feb 09 '23 00:02

SexyBeast


1 Answers

Maybe you could reimplement in MainWindow or in AppMenu the changeEvent.

void MainWindow::changeEvent(QEvent *event)
{
    if (event->type() == QEvent::LanguageChange) {
        this->retranslateUi(this);
        quickStart->retranslateUi(quickStart);
        //etc...
    } else {
        QMainWindow::changeEvent(event);
    }
}

You could force Widgets to retranslate themselves. But you need to have registered some QTranslator first.

For example, in the constructor of MainWindow (or in some config dialog) if it's possible to change language at runtime (what I've done in my software):

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);
}

Where language() returns "fr", "gb" or "cs" (initialized from a signal emitted when one has chosen a new language in options).

/** 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 :("));
    }
}

I hope it's helping.

like image 166
MBach Avatar answered Feb 11 '23 14:02

MBach