在Qt应用程序菜单栏的主菜单中添加和本地化菜单项

时间:2015-09-18 18:51:07

标签: c++ macos qt qmenu qmenubar

首先,这里是Evernote菜单的截图,用法语本地化:

[enter image description here]

正如您所看到的,主菜单中的所有菜单项(通过主菜单,我的意思是名称为应用程序名称的菜单项,如此处 Evernote )都使用法语进行本地化。 Evernote应用程序本身带来了许多菜单项,例如ÉvaluezEvernotepour Mac Mac版本的电子邮件 ),信息du compte ... 帐户信息...... )等。另外还有标准的OS X提供的菜单项,例如退出Evernote < / strong>,偏好等也是本地化的。

我的问题:

  1. 如何在此主菜单中添加新项?如何访问此菜单添加项目?
  2. 如何根据我的应用本地化来本地化这些项目,OS X提供的默认项目和我添加的项目是什么?
  3. 在Evernote菜单中,除了服务菜单选项外,所有内容似乎都已本地化(但子菜单选项已本地化!)?不能这也是本地化的吗?
  4. 我尝试过:

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

2 个答案:

答案 0 :(得分:4)

也许您可以在MainWindowAppMenu 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);
}

语言()返回&#34; fr&#34;,&#34; gb&#34;或者&#34; cs&#34; (从选项中选择新语言时发出的信号初始化。)

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

我希望它有所帮助。

答案 1 :(得分:3)

我仍然没有找到问题的完整答案。但是这里我在过去几天做了一些观察:

  1. 为了能够在主菜单中添加菜单项,您必须相应地设置菜单角色,即在将其添加到任何您想要的位置之后(因为它会移出而无关紧要),像这样设置菜单角色:

    fYourAction->setMenuRole(QAction::ApplicationSpecificRole);
    
  2. 这将在主菜单中添加菜单项。如果以这种方式添加多个项目,它们将按照您设置菜单角色的顺序显示。

    1. Qt已经提供了很少的特定角色 - 例如 About <app> 项目, Quit <app> 项目, { {1}} 项目等。提到here。 例如,如果您的操作有文本“Foo”,并将其作为菜单项添加到某处,并将角色设置为

      Preferences...
    2. 然后它会自动移动到主菜单并显示为 fFooAction->setMenuRole(QAction:: PreferencesRole); ,您实际放入动作的文字将无关紧要。但是,作为对 Preferences... 信号的响应,您附加到它的任何插槽仍将正确触发。同样适用于 triggered() ,无论您在该操作中添加什么文字,它都会移至主菜单并显示为 QAction::AboutRole 。< / p>

      1. About <your_app_name> QAction::AboutRole 的问题就像我说的那样,即使你尝试也不会本地化。它们只有在系统区域设置发生变化时才会进行本地化,如果您通过安装新的翻译器在应用程序中进行更改,它将不会更改。解决方法?避免使用 QAction:: PreferencesRole ,以便在主菜单中显示所有项目。然后根据您的自定义翻译器对它们进行适当的本地化,并且会尊重您在操作中提供的任何文本,即如果您在操作中将 foo 作为文本,它将显示为 foo < / strong>在主菜单中,并相应地进行本地化。再次,请注意,当您添加多个项目时,按照其外观顺序设置项目的角色,即模拟上面的Evernote菜单,首先设置 QAction::ApplicationSpecificRole 操作,然后是 about_app 操作。添加它们的位置并不重要,因为它们将被移动到新菜单,因此为项目设置菜单角色的顺序将决定它们在主菜单中的显示顺序。

      2. 上述方法的问题是我不知道如何在我在主菜单中添加的项目之间插入分隔符。在我们添加的菜单中很容易做到这一点,因为我们可以访问菜单对象,但是这里我们没有访问权限(我们在其他地方添加项目,并通过设置菜单角色使它们移动到主菜单),所以我还不知道如何在主菜单中添加多个分隔符。