QApplicationが重要なイベントを処理するときに、いくつかの異常な動作に気づきました。これは、私が作成したいと思っていた小さなゲームを危険にさらします。
キーを押したままにすると、一度トリガーしてキーが解放されてもう一方がトリガーされるのを待つのではなく、keyPressEvent
thenメソッドが繰り返し(そして非常に頻繁に)呼び出されます(これは望ましい、確かに期待される動作です)。keyReleaseEvent
keyPressEvent
これにより、パフォーマンスの大きな問題が発生します。複数のキーを押したままにすると、プログラムによって一部が完全に無視されるようになります。これは、おそらくイベントキューが問題になっているためです。
このプログラムは、繰り返される呼び出しを示しています。
from PyQt4 import QtGui
import sys
class Window(QtGui.QWidget):
def __init__(self):
super(Window, self).__init__()
def keyPressEvent(self, event):
print 'PRESSED'
event.accept()
def keyReleaseEvent(self, event):
print 'RELEASED'
event.accept()
app = QtGui.QApplication(sys.argv)
Window().show()
sys.exit(app.exec_())
このプログラム(Qtのゲームの可能性をテストするために使用していたばかげたグラフィカルなもの)は、既存のキーを保持するときに新しく押されたキーを無視することを示しています。
from PyQt4 import QtGui
import sys
class Window(QtGui.QWidget):
def __init__(self):
super(Window, self).__init__()
self.resize(100,300)
self.lower, self.upper = 10, -10
self.keys = [81, 65, 90, 87, 83, 88, 69, 68, 67, 82, 70, 86, 84, 71,
66, 89, 72, 78, 85, 74, 77, 73, 75, 44, 79, 76, 46, 80, 59, 47]
self.dots = [self.lower] * len(self.keys)
def keyPressEvent(self, event):
pressed = event.key()
if (pressed in self.keys):
index = self.keys.index(pressed)
self.dots[index] = self.height()+self.upper
self.repaint()
event.accept()
def keyReleaseEvent(self, event):
pressed = event.key()
if (pressed in self.keys):
index = self.keys.index(pressed)
self.dots[index] = self.lower
self.repaint()
event.accept()
def paintEvent(self, event):
step = self.width() / (len(self.dots) + 1)
painter = QtGui.QPainter()
painter.begin(self)
x, y = 0, 0
for w in self.dots:
i, j = x + step, w
painter.drawLine(x, self.height() - y, i, self.height() - j)
x, y = i, j
painter.end()
app = QtGui.QApplication(sys.argv)
Window().show()
sys.exit(app.exec_())
上記のプログラムを実行するとわかるように、3つまたは4つを超えるキーを押し続けると、現在保持されているキーが解放されるまで、新しいスパイクは確立されません。
keyPressEvent
物理的に解放されていないキーに対して1回だけトリガーされるような、この動作を防ぐにはどうすればよいですか?