简体   繁体   English

使用 Qt 检查密钥是否已关闭

[英]Check if a Key is Down with Qt

I am playing around with some graphics, and I have implemented simple camera movement with the arrow keys.我正在玩一些图形,并且我使用箭头键实现了简单的相机移动。 My first approach was to override keyPressEvent to do something like this:我的第一种方法是覆盖keyPressEvent来做这样的事情:

switch(key)
{
   case up: MoveCameraForward(step); break;
   case left: MoveCameraLeft(step); break;
   ...
}

This doesn't work as I wish it would.这并不像我希望的那样工作。 When I press and hold, for example, the forward key, the camera moves forward "step" units, then halts for a while and then continues moving.例如,当我按住前进键时,相机向前移动“步进”单位,然后暂停一段时间,然后继续移动。 I am guessing that this is how the event is generated, in order to avoid multiple events in case of a little bit long keypress.我猜测这就是事件的生成方式,以避免在按键时间过长的情况下出现多个事件。

So, I need to poll the keyboard in my Paint() routine.所以,我需要在我的Paint()例程中轮询键盘。 I haven't found how to do it with Qt.我还没有找到如何用 Qt 做到这一点。 I thought of having a map<Key, bool> which would be updated in keyPressEvent and keyReleaseEvent and poll that map in Paint() .我想有一个map<Key, bool>它将在keyPressEventkeyReleaseEvent更新,并在Paint()轮询该地图。 Any better ideas?有什么更好的想法吗? Thanks for any insights.感谢您提供任何见解。

这并不能解决检测按下哪些键的一般问题,但如果您只是在寻找键盘修饰符(shift、ctrl、alt 等),您可以通过静态QApplication::keyboardModifiers()QApplication::queryKeyboardModifiers()检索它QApplication::queryKeyboardModifiers()方法。

So, I need to poll the keyboard in my Paint() routine.所以,我需要在我的 Paint() 例程中轮询键盘。 I haven't found how to do it with Qt.我还没有找到如何用 Qt 做到这一点。 I thought of having a map which would be updated in keyPressEvent and keyReleaseEvent and poll that map in Paint().我想有一个地图,该地图将在 keyPressEvent 和 keyReleaseEvent 中更新,并在 Paint() 中轮询该地图。

Your second method is what I would have done, except that I would use a continuous, periodic QTimer event to poll the keyboard-pressed map and call QWidget::Update() function when necessary to invalidate the display widget instead.你的第二种方法是我会做的,除了我会使用一个连续的、周期性的 QTimer 事件来轮询键盘按下的地图并在必要时调用 QWidget::Update() 函数来使显示小部件无效。 Performing non-painting operations inside Paint() is strongly discouraged for many reasons but I do not know how to explain that well.出于多种原因,强烈建议不要在 Paint() 内执行非绘画操作,但我不知道如何解释得很好。

There is no Qt API for checking whether a key is pressed or not.没有用于检查键是否被按下的 Qt API。 You may have to write separate code for different platforms and add a bit of #ifdef logic.您可能需要为不同的平台编写单独的代码并添加一些#ifdef逻辑。

On Windows you can use GetKeyState() and GetKeyboardState() , both declared in windows.h .在 Windows 上,您可以使用GetKeyState()GetKeyboardState() ,两者都在windows.h声明。

This is not straight forward when using Qt, but the Gluon team has been working on exactly that problem (along with a bunch of others).这在使用 Qt 时并不直接,但 Gluon 团队一直在解决这个问题(以及其他一些问题)。 GluonInput solves the issue, and is available as part of Gluon: http://gluon.gamingfreedom.org/ It is also a nice, Qt-like API, so while it's an extra dependency, it should be possible for you to use it. GluonInput 解决了这个问题,并作为 Gluon 的一部分提供: http ://gluon.gamingfreedom.org/ 它也是一个不错的、类似 Qt 的 API,所以虽然它是一个额外的依赖项,但您应该可以使用它.

This is caused by auto repeation of keys:这是由自动重复键引起的:

When I press and hold, for example, the forward key, the camera moves forward "step" units, then halts for a while and then continues moving.例如,当我按住前进键时,相机向前移动“步进”单位,然后暂停一段时间,然后继续移动。

In QT5 you can detect key held down by function isAutoRepeat() of QKeyEvent object.在 QT5 中,您可以通过QKeyEvent对象的函数isAutoRepeat()检测按下的键。 If the key is held down then isAutoRepeat() will return true .如果按住该键,则isAutoRepeat()将返回true for example:例如:

void MainWindow::keyPressEvent(QKeyEvent *event)
{
    if (event->isAutoRepeat())
    {
        return;
    }

    if (!event->isAutoRepeat())
    {
        qDebug() << "[MainWindow::keyPressEvent()] " << event->key() << "; " << event->isAutoRepeat();
    }
}

void MainWindow::keyReleaseEvent(QKeyEvent *event)
{
    if (event->isAutoRepeat())
    {
        return;
    }
    qDebug() << "[MainWindow::keyReleaseEvent()] " << event->key() << "; " << event->isAutoRepeat();
}

在 Qt5 中使用 QGuiApplication::keyboardModifiers() 和 QGuiApplication::queryKeyboardModifiers() 作为键盘修饰符

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM