在大多数应用程序中,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似乎在每个操作系统上都有相同的行为。)
答案 0 :(得分:0)
目前,Qt没有提供任何机制来标记小部件是否“可以”剪切,复制和粘贴。你需要实现自己的。无论您采取何种解决方案,都有两个方面。
API暴露给应用程序的其余部分。 Cocoa API非常简单。我认为,在Creator中公开的API也相当简单。
实现该API所需的粘合代码。这段代码可能非常复杂,因为你只需要执行一次,然后不管它。
如果创作者的代码适合您,那么没有理由(除许可之外)不使用它。遗憾的是,可编辑小部件不提供通用接口,因此需要额外的工作。这样的工作可能更适合Qt源代码 - 这是获得Qt源的好处。
简单的API及其复杂的实现没有任何问题。这几乎就是Qt。一个简单的信号槽连接机制需要 lot 代码才能正确实现它(而不是只在纸上工作的“教科书”实现)。