Strange multiple keys pressed problem - 2D Game Qt !
-
Hi all,
I am currently developing a small 2D game with Qt C++.
I was just trying some little things before starting dev. the game.The problem is that I can't catch more than 3 key pressed at the same time.
I need this because I want to play with 2 - 4 players on the same PC and on the same keyboard.
If I don't find a solution my players won't be able to play at the same time, and that's a problem because it's a real time game.I am using the basic keyPressEvent to catch key pressed.
Then I store the keys in a QMap(int, bool), to know witch key is pressed and not pressed.
I am also using a timer to treat the QMap values and do some actions when one or more keys are pressed.
The problem is when 3 key are pressed and held down and I press a 4th key.
The 4th key is not catch, actually the program don't call any more the keyPressEvent.My code is following :
widget.h
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QtWidgets> class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = 0); ~Widget(); private: QTimer *timer; QMap<int, bool> keys; void keyPressEvent(QKeyEvent *event); void keyReleaseEvent(QKeyEvent *e); private slots: void timerOutEvent(); }; #endif // WIDGET_H
Widget.cpp
#include "widget.h" Widget::Widget(QWidget *parent) : QWidget(parent) { timer = new QTimer(); timer->setInterval(1000/60); timer->start(); connect(timer, &QTimer::timeout, this, &Widget::timerOutEvent); } Widget::~Widget() { } void Widget::timerOutEvent() { QString txt = ""; if(keys[Qt::Key_Up]) { txt += "u"; } if(keys[Qt::Key_Down]) { txt += "d"; } if(keys[Qt::Key_Left]) { txt += "l"; } if(keys[Qt::Key_Right]) { txt += "r"; } qDebug() << txt; } void Widget::keyReleaseEvent(QKeyEvent *event) { keys[event->key()] = false; QWidget::keyReleaseEvent(event); } void Widget::keyPressEvent(QKeyEvent *event) { keys[event->key()] = true; QWidget::keyPressEvent(event); }
main.cpp
#include "widget.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); Widget w; w.show(); return a.exec(); }
Thank you in advance for your help !
Alex -
I found the answer, and I post it on stackoverflow :
https://stackoverflow.com/questions/46949341/qt-multiple-keys-pressed-at-once/ -
I found also a great solution. You can add as class member:
QSet<int> pressedKeys;
And you can catch the key events in an event filter:bool MyWidget::eventFilter(QObject * obj, QEvent * event) { if(event->type()==QEvent::KeyPress) { pressedKeys += ((QKeyEvent*)event)->key(); if( pressedKeys.contains(Qt::Key_Up) && pressedKeys.contains(Qt::Key_Left) ) { // up and left is pressed } } else if(event->type()==QEvent::KeyRelease) { pressedKeys -= ((QKeyEvent*)event)->key(); } return false; }
and install the event filter in the constructor:
this->installEventFilter(this);
Reference: https://stackoverflow.com/questions/23816380/using-multiple-keys-in-qt-c
Project where I use it:
https://youtu.be/YuSc8oCXHxk