如何在同一时间长按键处理短按键?

时间:2016-04-12 18:37:33

标签: python python-3.x pyqt pyqt4

我尝试用Python和PyQt4编写简单的游戏。这是一个简单的平台游戏,我想处理"跳跃"按键期间"移动"按键。

就像我拿着right arrow键一样,同时我按下z(或者只是按任意键,可能是shift,ctrl,cmd ,alt)我希望继续向右移动,同时执行跳跃。

当我使用keyPressEvent时,它可以正常使用#34;移动"按键,但每次跳跃"按键打破了移动,我需要按箭头继续。

为了更好地理解我想要实现的目标,请看一下: (>是移动的右箭头,z是跳跃)

key: >>>>>>>>>>>>> . z . . o player: oooooooo

你可以看到我正在举行>和玩家移动。在我按z玩家跳跃并停止的同时,即使仍然按下>键。

是否可以在pyqt中执行此操作?也许我需要一些外部库?任何帮助将不胜感激!

解决!

感谢@Brendan Abel的回答,我已经做了我需要的一切:) 代码看起来与此类似(为了清晰起见,我已经简化了):

class Test(QtGui.QMainWindow):
  pressed_keys = {
    QtCore.Qt.Key_Left: False,
    QtCore.Qt.Key_Right: False,
    QtCore.Qt.Key_Z: False,
  }

  def __init__(self):
    self.timer = QtCore.QTimer(self)
    self.timer.timeout.connect(self.key_action)
    self.timer.start(100)

    # definitions hidden for simplicity
    self.key_actions = {
      QtCore.Qt.Key_Left: self.player_move_backward,
      QtCore.Qt.Key_Right: self.player_move_forward,
      QtCore.Qt.Key_Z: self.player_jump,
    }

  def keyPressEvent(self, e):
    key = e.key()
    self.pressed_keys[key] = True

  def keyReleaseEvent(self, e):
    key = e.key()
    self.pressed_keys[key] = False

  def key_action(self):
    for key, is_pressed in self.pressed_keys.items():
      if is_pressed:
        action = self.key_actions[key]

        action()
        self.update()

我的游戏现在就像这样: jump and move

1 个答案:

答案 0 :(得分:1)

您可能需要对键盘状态进行某种类型的常规轮询,以确定要处理的控件。不幸的是,Qt没有用于轮询键盘状态的直接API。您必须通过维护具有 keypress 事件但没有 keyrelease 事件的键的全局映射来跟踪哪些键已关闭。然后定期轮询该地图以获取按下的键列表。

pressed_keys = set()

def keyPressEvent(self, event):
    pressed_keys.add(event.key())

def keyReleaseEvent(self, event):
    pressed_keys.remove(event.key())

添加键时,您可以选择是否要添加修饰键(即shift,ctrl,alt)(使用event.modifiers()),以及是否应该应用于只有他们第一次按下的键,或者它们是否应该适用于所有按下的键。

您可以使用QTimer进行投票。基本上,不是keyPressEvent触发您的游戏更新,而是基于QTimer.timeout更新。

timer = QTimer()
timer.timeout.connect(self.update_game)
timer.start(100)  # Update rate

@QtCore.pyqtSlot()
def update_game(self):
    if Qt.Key_Space in pressed_keys:
        ...
    if Qt.Key_Up in pressed_keys:
        ...

您也可以选择不使用QTimer进行更新并继续使用keypresskeyrelease事件来触发更新,但您仍需要保留持久的按键状态。