當QApplication處理關鍵事件時,我注意到了一些不尋常的行爲,這些行爲危害了我希望做的一個小遊戲。PyQt4 - 按住一鍵檢測頻繁的按下和釋放?
按住一個鍵可導致keyPressEvent
然後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
僅針對尚未物理釋放的密鑰纔會觸發一次?
我推斷這是有關這一點:http://stackoverflow.com/questions/876852/how-is-keyboard-auto-repeat-implemented-on-a-windows-pc?rq=1 我該如何解決這個問題? –
這可能不止一晚,但許多鍵盤無論如何都不支持超過3或4個同時按鍵。 – JAB