Qt - 移除快捷键 -- 快捷键重载不明确

5

无关信息: 我正在尝试使用Qt构建一个应用程序。这个应用程序包含一个QMdiArea和一个子窗口。我的子窗口将有一个菜单,可以集成到QMdiArea中,也可以分离并附加到子窗口本身。不过,这些细节不是必要的...

问题: 我想让我的子窗口小部件具有一个带有快捷键“CTRL+W”的菜单。但是,由于我正在使用QMdiArea,该快捷键已被使用,导致出现以下问题:

QAction::eventFilter: Ambiguous shortcut overload: Ctrl+W

如何摆脱这个快捷键并在我的子窗口小部件中声明它?

更新: 这是我尝试过但没有成功的方法:

class MDI : public QMdiArea
{
    Q_OBJECT
    private:
    bool event(QEvent *tEvent)
    {
        if (tEvent->type() == QEvent::KeyPress)
        {
            QKeyEvent* ke = static_cast<QKeyEvent*>(tEvent);
            if (ke->key()== Qt::Key_W && ke->modifiers() & Qt::ControlModifier)
            emit KeyCW();
            return true;
        }
        return QMdiArea::event(tEvent);
    }
public:
signals:
    void KeyCW();
};

这个方法能够成功,如果我只是像把 Qt::Key_W 改为 Qt::Key_L 这样简单的操作。快捷键会被接收并触发事件。但是使用 W 的时候,它永远都不会发生。我也尝试了将 event 移动到 QMainWindow 中,以及将 eventFilter 移动到 QMdiArea 的子窗口中。似乎这里有点过于复杂,仅仅想要从 QMdiArea 中移除默认的按键处理就显得有些简单了。
5个回答

3
您可以像这样禁用此快捷方式:
for( QAction *action : subWindow->systemMenu()->actions() ) {
    if( action->shortcut() == QKeySequence( QKeySequence::Close ) ) {
        action->setShortcut( QKeySequence() );
        break;
    }
}

2

当添加子窗口时,您可以使用Qt::CustomizeWindowHint作为附加标志,完全摆脱QMdiSubWindow的预定义关闭操作。

QMdiSubWindow *subWindow2 = mdiArea.addSubWindow(internalWidget2, 
                                                 Qt::Widget | Qt::CustomizeWindowHint | 
                                                 Qt::WindowMinMaxButtonsHint);

0

我能够通过为我的关闭操作设置快捷方式上下文来解决这个问题。将它设置为Qt::WidgetShortcut,我不再遇到模糊的快捷方式重载问题。以下是我现在设置关闭操作的方法:

  closeAction = new QAction(tr("&Close"), this);
  closeAction->setShortcut(Qt::CTRL|Qt::Key_W);
  closeAction->setShortcutContext(Qt::WidgetShortcut);
  connect(closeAction, SIGNAL(triggered()), mdiArea, SLOT(closeActiveSubWindow()));

0

0
继承 QMdiArea 并重新实现 keyPressEvent() 方法。这样应该就可以了。
  void keyPressEvent(QKeyEvent* event){

    if(event->key() == Qt::Key_W and event->modifiers() & Qt::ControlModifier){
      // handle it
    }else{
      return QMdiArea::keyPressEvent(event);
    }
  }

你也可以使用事件过滤器。我不太了解你的类层次结构,但希望你能理解这个想法。
bool CustomMdiArea::eventFilter(QObject *object, QEvent *event){
     if(object == yourChildWindow && event->type() == QEvent::KeyPress) {
         QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
         if(keyEvent->key() == Qt::Key_W and keyEvent->modifiers() & Qt::ControlModifier) {
             //handle it
             return true;
         }else{
             return false;
         }
     }
     return false;
 }

那么有没有办法禁用QMdiArea创建的快捷方式?基本上意味着如果我想使用快捷键,我必须在两者之间使用信号/槽连接吗? - Serodis
另外,如果那是唯一的方法,那么在小部件菜单上安装模糊的快捷方式是否会有任何危害?我真的不想牺牲菜单栏中“Ctrl+W”快捷方式的提醒,因为这是告诉用户快捷方式功能的最佳方式。 - Serodis
改变QMdiArea在特定键事件方面的默认行为是通过对其进行子类化并重新实现keyPressEvent()。另一种方法是使用事件过滤器。 - Arlen
这个问题似乎越来越深奥了,我完全被弄糊涂了。我考虑了你写的东西,为了让它工作,我必须继承QMdiArea并向QMainWindow发出一个信号,然后由QMainWindow处理。好吧,我决定试一试,但是...没有运气。我可以捕获其他键,但是即使通过QMdiArea的事件成员,我仍然没有收到CTRL + W键组合。我正在更新我的帖子以展示一些代码... - Serodis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接