代码之家  ›  专栏  ›  技术社区  ›  BastiBen

如何实现“撤消”、“剪切”、“粘贴”、“复制”的“编辑”菜单?

  •  7
  • BastiBen  · 技术社区  · 16 年前

    问候语,

    对于我的一个应用程序,我试图实现一个“编辑”菜单。这个菜单通常有标准的条目 撤消 , 切割 , 拷贝 粘贴 .

    这个菜单在默认情况下不存在,用户似乎特别期待它出现在MacOSX上。

    有没有一种更简单的方法来实现这个,而不需要在每个小部件中手动执行?由于大多数小部件已经通过快捷方式实现了复制/粘贴/撤消机制,所以我想提供一些简单的菜单操作来调用它们。

    我猜,这些动作应该先调用任何具有焦点的小部件,然后将事件向上传递到对象链。

    我在Windows、Linux和Mac OS X上使用Qt4.6。

    谢谢!

    3 回复  |  直到 10 年前
        1
  •  6
  •   user285740    16 年前

    很容易完成一半必需的功能。只需在主窗口类中创建编辑菜单和必要的Qactions(copy/paste/undo/etc),并将它们连接到插槽。在插槽中,模拟正确的按键和释放事件(例如,用于复制的ctrl+c),并将它们发送到当前聚焦的小部件。在代码中,如下所示:

    MainWindow::MainWindow(...)
    {
        ...
        connect( actionCopy, SIGNAL( triggered()), SLOT( copy()));
        ...
    }
    ...
    void MainWindow::copy()
    {
        QWidget* focused = QApplication::focusWidget();
        if( focused != 0 )
        {
            QApplication::postEvent( focused,
                                     new QKeyEvent( QEvent::KeyPress,
                                                    Qt::Key_C,
                                                    Qt::ControlModifier ));
            QApplication::postEvent( focused,
                                     new QKeyEvent( QEvent::KeyRelease,
                                                    Qt::Key_C,
                                                    Qt::ControlModifier ));
    }
    

    当然,这是一个相当大的黑客。您需要修改每个目标平台的代码,将键盘快捷键更改为正确的快捷键,并且接收焦点的小部件可能会使用ctrl+c执行一些出乎意料的安静操作。在我看来,此方法的最大缺点是无法正确控制编辑菜单项的启用状态。无法从通用小部件查询复制或粘贴操作是否可能。

    对于这个问题,我无法找到真正的解决方案——并且会惊讶地发现它的存在——因为复制/粘贴功能通常隐藏在类的代码中,而不是通过任何标准的信号集/槽暴露出来。在今晚的功能实验之后,我决定忘记从我的应用程序中有一个编辑菜单,并期望用户知道键盘快捷键,或者使用上下文相关的菜单。

        2
  •  0
  •   e8johan    16 年前

    我的印象是编辑菜单应用于中央文档小部件,而不是加载小部件。我还没有测试过,但是如果您有一个带有qlineedits的表单,那么编辑菜单(在菜单栏中)是否真的适用于这个小部件。你不是简单地打开上下文菜单或按快捷键来访问这些选项吗…

        3
  •  0
  •   Dmitry Isaev Ash Furrow    10 年前

    用户285740的解决方案对我没有帮助,因为我在应用程序中使用了浏览器控件(CEF或WebKit无关紧要)。

    为什么? 对于浏览器来说, focusWidget() 似乎总是 NULL ,因为 <input> 元素不是小部件。我试过 postEvent() 其他小部件-不起作用。添加菜单项 QAction::TextHeuristicRole +标准序列如 QKeySequence::Copy 也没有完成任务(我只能将它们连接到我的插槽,而不能连接到标准插槽)。CEFClient示例加载一个XIB文件,但它对我来说不是一个选项,因为qt从头开始创建所有内容。

    最终,我找到了解决办法!从Objective EC++代码创建相同的菜单项。他们的行为就像是通过 QMenuBar ,但!!)它们可以连接到一些真正的自动操作,比如 @selector(copy:)

    您可以在这里找到一个示例: nsMenuUtilsX::GetStandardEditMenuItem() ,只需从objc++代码中执行该操作。

    但是,如果您以前执行过此代码,则此代码不起作用 QApplication::exec() . qt然后以编程方式“重写”主菜单… 如何解决这个问题?好吧,也许我会添加一些黑客,比如qtimer。 如果不尝试通过qmenubar添加其他项,则不会这样做。现在没事了!Qt独立菜单。