Seite 1 von 1
Mehrere Tasteneingaben gleichzeitig verwerten
Verfasst: 15. Juli 2007 00:00
von LangerJan
Moin zusammen!
Ich bin neu hier, hab die Suchfunktion schon zu meinem Thema bemüht, aber nichts Entsprechendes gefunden. Sollte ich die Lösung wie den Wald vor lauter Bäumen nicht sehen, bitte ich um einen dezenten Hinweis
Ich habe da nun ein Widget, dass KeyEvents erhält. Auf einer 2D-Spielfläche (Eine QGraphicsScene) soll ein Raumschiff auf Tastendruck (Key_Left, Right, etc) rotiert werden und mit Schub/Rückschub bewegt werden.
So weit so gut. Diese Dinge klappen aber nur einzeln. Ich kann entweder rotieren oder Gas geben, aber nicht beides gleichzeitig. Halte ich bspw. "Links" gedrückt und drücke dann "Geradeaus", wird die Links-Operation abgebrochen und die Geradeaus-Operation beginnt.
Gibt es irgendeine Möglichkeit, dieses Problem zu umschiffen? Eventuell gibts ja bereits spezielle Methoden, die ich noch nicht kenne
Wenn ihr noch weitere Infos braucht, um mir zu helfen, fragt mich.
Besten Dank im Voraus!
Ciao
Jan
Verfasst: 15. Juli 2007 08:06
von upsala
Es gibt für (fast?) jede Taste ein keyPressEvent und ein keyReleaseEvent. Die ReleaseEvents kommen immer erst beim loslassen der Taste und nicht wenn eine andere gedrückt wurde. Also ist es Sache deiner Anwendung, dies richtig auszuwerten.
Verfasst: 15. Juli 2007 11:57
von LangerJan
Moin upsala, danke für deine Antwort
Das KeyReleaseEvent habe ich schon ausprobiert. Das Problem ist wohl:
Ich halte eine Taste gedrückt. Dieses "gedrückt halten" wird dann (betriebssystemabhängig) nach einer gewissen Zeit als schnell hintereinanderfolgendes Drücken (quasi "Dauerfeuer") interpretiert.
Ich möchte jetzt nur ungern diese Funktion in meinem OS abschalten. Kann man das nicht programmintern abfangen?
Verfasst: 15. Juli 2007 12:02
von Volker
Schon auf die Idee gekommen einfach ein Array von bool Werten anzulegen und je nach Tastencode den entsprechenden Eintrag im Array auf true setzen wenn die Taste gedrückt wurde und auf false im Fall des Release Events?
Dann brauchst Du in der Update Loop deines Spiels nur noch das Array auswerten.
Verfasst: 15. Juli 2007 12:46
von LangerJan
Wie gesagt, das ReleaseEvent wird bei "Dauerfeuer" gleich mit ausgelöst. Die Idee habe ich schon aus verschiedenen Quellen gehört und im englischsprachigem QT Forum habe ich nun auch eine (hoffentlich) passende Lösung gefunden:
Der Code stammt aus dem aktuellen QT Asteriods-Port und diese bool'sche Funktion habe ich noch nicht gekannt;
Code: Alles auswählen
void KAstTopLevel::keyPressEvent( QKeyEvent *event )
{
if ( event->isAutoRepeat() || !actions.contains( event->key() ) )
{
event->ignore();
return;
}
[...]
Ich werde das, in Kombination mit einem ReleaseEvent mal ausprobieren.
Danke für eure Hilfe! Wenn das hier geklappt hat, setze ich den Thread auf "gelöst"

Verfasst: 15. Juli 2007 12:47
von upsala
Das Betriebssystem sendet, bei gedrückt gehaltener Taste abwechselnd keyPress und keyRelease? Tja, dann läßt sich da programmtechnisch mit vernünftigen Aufwand nicht viel machen.
Verfasst: 15. Juli 2007 12:50
von LangerJan
upsala hat geschrieben:Das Betriebssystem sendet, bei gedrückt gehaltener Taste abwechselnd keyPress und keyRelease? Tja, dann läßt sich da programmtechnisch mit vernünftigen Aufwand nicht viel machen.
Ja, es sendet bei gedrückt gehaltener Taste die Tasteneingabe mehrfach.
Beispiel: "s" gedrückt halten, ergibt: ssssssssssssssssssssssssssssssss
Da ist jedes "s" Signal ein KeyPress und ein KeyRelease.
Ich probiere jetzt erstmal obiges aus.
Verfasst: 15. Juli 2007 13:58
von LangerJan
okay, hier die Lösung, wie ich sie implementiert habe:
Es gibt ein Array aus bool'schen Werte namens Tastenspeicher.
Code: Alles auswählen
void Hilfsfenster::keyPressEvent(QKeyEvent* event){
if(event->isAutoRepeat()){
event->ignore();
return;
};
switch (event->key()) {
case Qt::Key_Left: this->Tastenspeicher[0] = TRUE; break;
case Qt::Key_Right:this->Tastenspeicher[1] = TRUE; break;
case Qt::Key_Down: this->Tastenspeicher[2] = TRUE; break;
case Qt::Key_Up: this->Tastenspeicher[3] = TRUE; break;
case Qt::Key_Control: this->Tastenspeicher[4] = TRUE; break;
default: QWidget::keyPressEvent(event);
};
};
Eine separate Funktion ruft mit Hilfe eines QTimers regelmäßig das Array auf und "drückt" die "Tasten" manuell. Die KeyRelease Funktion ist identisch mit der Press Funktion, nur, dass die Werte wieder auf FALSE gesetzt werden.
Danke an alle!
Verfasst: 25. Juli 2007 17:26
von LangerJan
Jetzt ist doch noch ein Problem aufgetreten und ich weiß es mir nicht so recht zu erklären.
Angenommen, jemand hält wahllos 4 (von mir mit Funktionen belegte) Buchstabentasten gedrückt. Dann kommt kein anderes KeyEvent mehr durch. Ich kann dann jede beliebige Taste drücken, aber deren Funktion wird nicht mehr ausgeführt.
Wenn ich aber die vier Pfeiltasten gleichzeitig drücke, sind noch andere KeyPressEvents möglich.
Weiß dazu jemand Rat, wie ich alle KeyPressEvents durchbekomme?