2013-01-04 54 views
1

當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僅針對尚未物理釋放的密鑰纔會觸發一次?

+0

我推斷這是有關這一點:http://stackoverflow.com/questions/876852/how-is-keyboard-auto-repeat-implemented-on-a-windows-pc?rq=1 我該如何解決這個問題? –

+0

這可能不止一晚,但許多鍵盤無論如何都不支持超過3或4個同時按鍵。 – JAB

回答

3

使用event.isAutoRepeat()可能有幫助

例如,

def keyPressEvent(self, event): 
    if event.isAutoRepeat(): 
     return 
    pressed = event.key() 
    if (pressed in self.keys): 
     index = self.keys.index(pressed) 
     self.dots[index] = self.height()+self.upper 
     self.repaint() 
    event.accept() 
+0

這會停止反覆重新繪製,但不會重新佔用事件隊列中的寶貴空間,因此新的按鍵仍然被忽略。 –