如何在Qt中创建“编辑”菜单,特别是MacOSX

时间:2014-02-11 12:20:10

标签: c++ qt

在大多数应用程序中,MacOSX中的“编辑”菜单非常智能且简单:它会自动知道当前所选小部件是否响应相关的ObjC消息(cut:copy:,{{1 }},paste:)并且根据它,菜单操作是否显示为灰色。如果您触发操作,它只会将ObjC消息发送到当前选定的小部件。 Cocoa代码基本上是:

selectText:

除此之外,MacOSX检测到这是一个“编辑”菜单,并在菜单末尾自动添加“开始听写...”和“特殊字符...”。

现在我正在开发Qt,我想要完全符合这种行为(至少在我的应用程序的MacOSX版本中)。

关于SO,已经有两个相关问题:here (2011)here (2010)。然而,两者都有些过时,解决方案远非最优。

有一个应用程序QtCreator似乎做得对。但是,解决方案似乎相当复杂。我在代码中潜水了一下,有一些actionmanager,在mainwindow setup中,它将它连接起来:

mi = mainMenu.addItemWithTitle_action_keyEquivalent_("Edit", None, "")
m = AppKit.NSMenu.alloc().initWithTitle_("Edit")
mainMenu.setSubmenu_forItem_(m, mi)

m.addItemWithTitle_action_keyEquivalent_('Cut', 'cut:', 'x')
m.addItemWithTitle_action_keyEquivalent_('Copy', 'copy:', 'c')
m.addItemWithTitle_action_keyEquivalent_('Paste', 'paste:', 'v')
m.addItemWithTitle_action_keyEquivalent_('Select all', 'selectText:', 'a')

然后,每个相关的小部件似乎在该动作管理器中注册自己,例如texteditor

Context globalContext(Constants::C_GLOBAL);
...
// Select All
icon = QIcon::fromTheme(QLatin1String("edit-select-all"));
tmpaction = new QAction(icon, tr("Select &All"), this);
cmd = am->registerAction(tmpaction, Constants::SELECTALL, globalContext);
cmd->setDefaultKeySequence(QKeySequence::SelectAll);
medit->addAction(cmd, Constants::G_EDIT_SELECTALL);
tmpaction->setEnabled(false);

这一切似乎都太过分了,尤其是与Cocoa解决方案相比。

我想知道是否有更简单/更清晰的解决方案,更像是Cocoa代码。我想到了用m_copyAction = registerNewAction(QLatin1String(Core::Constants::COPY), this, SLOT(copyAction()), true); m_cutAction = registerNewAction(QLatin1String(Core::Constants::CUT), this, SLOT(cutAction()), true); m_pasteAction = registerNewAction(QLatin1String(Core::Constants::PASTE), this, SLOT(pasteAction()), true); m_modifyingActions << m_pasteAction; m_selectAllAction = registerNewAction(QLatin1String(Core::Constants::SELECTALL), this, SLOT(selectAllAction()), true); copy,...插槽创建一些代理对象,这些插槽本身会尝试动态调用当前所选小部件上的相关方法/插槽(如果它们可用)。不确定这是否会在以后引起其他问题。

另外,在我的情况下,我的应用程序可能没有在MacOSX上打开任何窗口(与QtCreator相反),这是主菜单,但我想这是不相关的。

另外,我不习惯其他操作系统的用户指南。在Windows / Linux上,相同的行为是否有意义?当然,在这些平台上,没有主菜单 - 菜单对某些窗口来说会很紧张。 (QtCreator似乎在每个操作系统上都有相同的行为。)

1 个答案:

答案 0 :(得分:0)

目前,Qt没有提供任何机制来标记小部件是否“可以”剪切,复制和粘贴。你需要实现自己的。无论您采取何种解决方案,都有两个方面。

  1. API暴露给应用程序的其余部分。 Cocoa API非常简单。我认为,在Creator中公开的API也相当简单。

  2. 实现该API所需的粘合代码。这段代码可能非常复杂,因为你只需要执行一次,然后不管它。

  3. 如果创作者的代码适合您,那么没有理由(除许可之外)不使用它。遗憾的是,可编辑小部件不提供通用接口,因此需要额外的工作。这样的工作可能更适合Qt源代码 - 这是获得Qt源的好处。

    简单的API及其复杂的实现没有任何问题。这几乎就是Qt。一个简单的信号槽连接机制需要 lot 代码才能正确实现它(而不是只在纸上工作的“教科书”实现)。