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:
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. I haven't found how to do it with Qt. I thought of having a map<Key, bool>
which would be updated in keyPressEvent
and keyReleaseEvent
and poll that map in Paint()
开发者_运维知识库. Any better ideas? Thanks for any insights.
This doesn't solve the general problem of detecting which keys are pressed, but if you are only looking for keyboard modifiers (shift, ctrl, alt, etc.), you can retrieve that through the static QApplication::keyboardModifiers()
and QApplication::queryKeyboardModifiers()
methods.
So, I need to poll the keyboard in my Paint() routine. I haven't found how to do it with Qt. I thought of having a map which would be updated in keyPressEvent and keyReleaseEvent and poll that map in 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. Performing non-painting operations inside Paint() is strongly discouraged for many reasons but I do not know how to explain that well.
There is no Qt API for checking whether a key is pressed or not.
You may have to write separate code for different platforms and add a bit of #ifdef
logic.
On Windows you can use GetKeyState()
and GetKeyboardState()
, both declared in 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). 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.
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. If the key is held down then isAutoRepeat()
will return 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();
}
Use QGuiApplication::keyboardModifiers() and QGuiApplication::queryKeyboardModifiers() for keyboard modifiers in Qt5
精彩评论