如何在 Linux 上禁用 Qt 捕获小部件焦点导航的箭头键的行为

Ste*_*eve 5 linux keyboard events qt

我正在开发一个主要在 MacOS 上开发的 Qt 应用程序,但随后也在 Linux 上构建和测试。

我们在主窗口类中定义一个 keyPressEvent() 方法来响应某些键盘事件。其中,我们响应 Qt::Key_Left、Qt::Key_Right 和 Qt::Key_Space。这在 MacOS 上效果很好。然而,在 Linux 上,我们永远不会收到这些事件。

进行一些谷歌搜索(并通过我们的应用程序在 Linux 上的行为进行确认),似乎其原因是 Qt 使用这些键在应用程序的 GUI 中对按钮小部件进行键盘导航。如果我在 Linux 上按箭头键,我会循环浏览所有活动按钮小部件,依次选择每个按钮小部件。如果我单击空格键,则按下当前选定的按钮。

到目前为止,我通过谷歌搜索所能找到的只是关于如何对特定按钮进行子类化或应用过滤器的建议,以避免通过让按钮忽略事件并将其传递来避免这种行为。但我不想对我放入 GUI 中的每个按钮小部件都执行此操作。那太蹩脚了。

有没有办法全局禁用此行为并允许我的应用程序代码实际获取所有箭头键和空格键事件?

Pav*_*hov 2

您可以设置添加全局事件监听器来捕获这些事件。

在窗口构造函数中:

QApplication::instance()->installEventFilter(this);
Run Code Online (Sandbox Code Playgroud)

在窗口的 eventFilter 方法中:

bool MainWindow::eventFilter(QObject *object, QEvent *event) {
  if (event->type() == QEvent::KeyPress) {
    QKeyEvent* key_event = static_cast<QKeyEvent*>(event);
    qDebug() << "key" << key_event->key() << "object" << object;
    //...
  }
  return false;
}
Run Code Online (Sandbox Code Playgroud)

如果您已经处理了一个事件,您应该true从此函数返回。您可以使用object变量来找出事件的来源。例如,它可以是一些QPushButton。如果有必要,您可以检查此按钮是否是主窗口的子窗口(如果您有多个顶部窗口)。

另一种方法是完全禁用按钮的焦点。将按钮设置focusPolicyNoFocus。那么他们就不会捕捉到关键事件。

您也可以子类化 QPushButton 并keyPressEvent使用空实现重新实现。