python - PyQt4 - 按住一个被检测为频繁按下和释放的键?

标签 python pyqt4 keypress eventqueue keyrelease

当 QApplication 处理关键事件时,我注意到一些异常行为,这会危及我希望制作的小游戏。

按住一个键会导致 keyPressEventkeyReleaseEvent 方法被重复(并且非常频繁)调用,而不是触发一次 keyPressEvent并等待释放 key 以触发另一个 key (这是期望的和公认的预期行为)。

这会导致巨大的性能问题,在某种程度上,按住多个键会导致某些键被程序完全忽略,大概是因为事件队列正在受到影响。

这个程序演示了重复调用:

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 只针对尚未物理释放的键触发一次?

最佳答案

使用 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()

关于python - PyQt4 - 按住一个被检测为频繁按下和释放的键?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14159318/

相关文章:

java - KeyPressed/KeyReleased 不起作用?

python - 在 DataFrame 中的新标题列下嵌套列

python - Pyside PyQt,如何将 Key_Delete 连接到 4 个不同的 QListWidget

python-3.x - QPainter.drawText 丑陋的字体渲染

linux - Linux 终端中是否有用于按键的预输入缓冲区?

python - 如何检测按键?

python - open 如何处理上下文管理?

python - 传递异常并执行下一行代码

Python MySQLdb唯一记录,忽略错误

python - 使用 setBold 方法在标签中使用粗体字体