4

我是 Qt 的新手,但我正在尝试在 Qt 应用程序中实现基本上相当于视频游戏式输入循环的东西(我知道这很疯狂,但看看你能不能帮忙)。我需要准确的、一对一的按键按键释放事件处理,包括修饰符在内的所有按键,无论您多么奇怪地敲击键盘。

当然,您对关键事件的主要访问是通过QKeyEvent. 但是,假设发生以下情况:

  • 用户按住Ctrl
  • 用户按住Up
  • 用户发布CtrlUp同时

据我所知,我从 Qt 得到的是:

  • QKeyEvent 用于单独按下Ctrl, ( Qt::Key_Ctrl)
  • QKeyEvent 用于单独按下Up, ( Qt::Key_Up)
  • QKeyEvent 用于释放Ctrl+Up, withkey() == Qt::Key_Up和 Ctrl 位反映在修饰符的变化中。

这可能并不完全准确,但这是我对问题调试过多的最佳猜测。无论如何,涉及修饰符时的按键释放事件是非常不可靠的。

最后的 Ctrl+Up 序列是问题所在。现在,我知道我得到了修饰符状态e->modifiers(),并且我得到了按键e->key()。我可以做一些复杂的修改,尝试在内部记住修改器状态,以检测用户何时释放修改器。但是随后,Qt 文档告诉我,说到e->modifiers()

这个函数不能总是被信任。例如,用户可以通过同时按下两个 Shift 键并释放其中一个来混淆它。

这正是我试图避免的情况。

有没有可靠的方法来跟踪 Qt 中的普通键和修饰键的一对一按键按下和释放?如果不是,你能得到的最接近的是什么?

编辑:我可以稍微改进一下。似乎如果您Cmd在 Mac 上按住,按几个键(比如字母键),释放它们,然后 release Cmd,您不会收到字母键释放的释放事件。 我将尝试隔离一个小例子,看看这是否真的是一个 Qt 错误。

4

2 回答 2

2

我认为如果您对键盘非常具体,您将离开 Qt 并获得特定于操作系统的东西,或者您需要在任何过滤发生之前处理 Qt 事件。

在过滤之前处理 Qt 事件

Qt 中的加速器查找并等待 Alt+__ 组合,您可以设置 Ctrl+__ 组合以供 QAction 监听。

QApplication 和一般 GUI 环境中内置的这两种类型的对象可能会中断您收到的消息,并且给您的消息比您期望的要少。

Qt 文档:事件系统 ...这部分有指向此的链接...

QCoreApplication::notify() ... 它告诉最高级别可以编写 Qt 应用程序以使用 Qt API 处理输入:

在 上安装事件过滤器QCoreApplication::instance()。这样的事件过滤器能够处理所有小部件的所有事件,因此它与重新实现 notify() 一样强大;此外,可以有多个应用程序全局事件过滤器。全局事件过滤器甚至可以看到禁用小部件的鼠标事件。请注意,应用程序事件过滤器仅对存在于主线程中的对象调用。

操作系统特定的键盘处理替代方案

如果从安装在上述级别的 Qt 事件过滤器查看调试语句产生的结果与您在问题中提到的结果相同,那么您将需要转到特定于操作系统的键盘输入内容。例如,在 Windows 中,您需要扫描键盘或查看整个键盘的 VK 状态并对其进行处理(使用类似 的东西GetKeyboardState())。

于 2012-06-14T02:50:34.860 回答
0

我知道现在回答这个问题有点晚了。仍然......我对 Mac 密钥发布事件有同样的问题,并且存在一个未解决的错误 QTBUG-36839。在 Windows 上,您可以实现键盘挂钩来捕获每个按键/释放。但即使这样在某些情况下也不可靠。例如,如果您在解锁后键入锁屏快捷方式,您将看不到任何按键释放。我想Mac上一定有类似钩子的东西。如果记住用户究竟按下了什么物理键对您很重要——我认为这是最好的方法之一。同时,根据我的经验,做一些低级的事情会花费很多时间,并且可能会在你无法想象的情况下带来奇怪的错误。所以问题是:你确定你不能用像 QAction 这样的东西来做你需要的东西吗?或者,也许您可​​以在快捷方式中使用 Control 而不是 Command :)

于 2016-02-19T10:57:17.067 回答