如何使用“撤消”,“剪切”,“粘贴”和“复制”来实现“编辑”菜单?

时间:2010-01-12 07:47:18

标签: user-interface qt menu copy-paste

问候,

我的一个应用程序我正在尝试实现“编辑”菜单。此菜单通常包含标准条目撤消剪切复制粘贴

默认情况下,此菜单不存在,用户似乎特别希望在Mac OS X上使用它。

有没有一种更简单的方法来实现这一点,而不是手动在每个小部件中这样做?由于大多数小部件都具有已通过快捷方式实现的复制/粘贴/撤消机制,因此我想提供一些简单的菜单操作来调用它们。

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

我在Windows,Linux和Mac OS X上使用Qt 4.6。

谢谢!

3 个答案:

答案 0 :(得分:6)

完成一半必要的功能很容易。只需在主窗口类中创建“编辑”菜单以及必要的QAction(复制/粘贴/撤消/等),然后将它们连接到插槽。在插槽中,模拟正确的按键和释放事件(例如,Ctrl + C for Copy)并将它们发送到当前聚焦的小部件。在代码中,像这样:

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执行某些安静意外操作。在我看来,这种方法最糟糕的缺点是你无法正确控制编辑菜单项的启用状态。无法从通用窗口小部件查询是否可以进行复制或粘贴操作。

我无法找到这个问题的真正解决方案 - 并且会惊讶地发现存在这个问题 - 因为复制/粘贴功能通常隐藏在类代码中并且不通过任何标准信号集公开/插槽。在今晚使用该功能进行实验后,我决定忘记从我的应用程序中获取编辑菜单,并希望用户知道键盘快捷键,或使用上下文相关菜单。

答案 1 :(得分:0)

我的印象是“编辑”菜单适用于中央文档小部件,而不是小型的小部件。我没有测试过,但是如果你有一个带有QLineEdits的表单,编辑菜单(在菜单栏中)是否真的适用于该窗口小部件。你不是简单地调出上下文菜单或按快捷键来访问这些选项......

答案 2 :(得分:0)

为此我能找到的最佳解决方案来自https://www.qtcentre.org/threads/10709-using-cut()-copy()-paste()。在我的应用中,结果最终看起来像这样:

connect(ui->actionCut, &QAction::triggered, []() {
    QWidget *focusWidget = QApplication::focusWidget();
    QLineEdit *lineEdit = dynamic_cast<QLineEdit*>(focusWidget);
    QTextEdit *textEdit = dynamic_cast<QTextEdit*>(focusWidget);

    if (lineEdit && lineEdit->isEnabled() && !lineEdit->isReadOnly())
        lineEdit->cut();
    else if (textEdit && textEdit->isEnabled() && !textEdit->isReadOnly())
        textEdit->cut();
});

这真的很糟糕,必须对每个标准菜单项(撤消,重做,剪切,复制,粘贴,删除,全选...)进行操作,并正确启用/禁用菜单项需要跳更多的篮球。这是我第一次将Cocoa应用程序移植到Qt时,我感到Qt明显次于标准(在这种情况下,Qt根本不存在Cocoa的第一个响应器机制)。不过,我认为它比user285740提出的解决方案更好,该解决方案对特定的键盘操作进行了硬编码。 YMMV。