python一个按钮控制两个事件,Python绑定-允许同时按下多个键

I have a problem in Python.

I'm using Tkinter and have four bind events, that listen to key presses on my form.

My problem is, that these don't run asynchronously. So, for example I can press one button, and the events are recognized. But when I press and hold two keys at the same time, just one event gets fired.

Is there an alternative way to do this?

self.f.bind("w", self.player1Up)

self.f.bind("s", self.player1Down)

self.f.bind("o", self.player2Up)

self.f.bind("l", self.player2Down)

解决方案

Unfortunately, you are somewhat at the mercy of the underlying auto-repeat mechanism of your system. For example, on the mac I'm using at the moment if I press and hold "w" I'll get a stream of press and release events. While pressed, if I press "o" I get a stream of presses and releases for "o" but no more events for "w".

You will need to set up a mini state machine, and bind to both key press and key release events. This will let you track which keys are pressed and which are not. Then, each time you draw a frame you can query the machine to see which keys are pressed and act accordingly.

Here's a quick hack I threw together. I've only tested it on my mac, and only with python 2.5. I've made no real attempt at being "pythonic" or efficient. The code merely serves to illustrate the technique. With this code you can simultaneously press either "w" or "s" and "o" or "l" to move two paddles up and down.

'''Example that demonstrates keeping track of multiple key events'''

from Tkinter import *

class Playfield:

def __init__(self):

# this dict keeps track of keys that have been pressed but not

# released

self.pressed = {}

self._create_ui()

def start(self):

self._animate()

self.root.mainloop()

def _create_ui(self):

self.root = Tk()

self.p1label = Label(text="press w, s to move player 1 up, down",

anchor="w")

self.p2label = Label(text="press o, l to move player 2 up, down",

anchor="w")

self.canvas = Canvas(width=440, height=440)

self.canvas.config(scrollregion=(-20, -20, 420, 420))

self.p1label.pack(side="top", fill="x")

self.p2label.pack(side="top", fill="x")

self.canvas.pack(side="top", fill="both", expand="true")

self.p1 = Paddle(self.canvas, tag="p1", color="red", x=0, y=0)

self.p2 = Paddle(self.canvas, tag="p2", color="blue", x=400, y=0)

self._set_bindings()

def _animate(self):

if self.pressed["w"]: self.p1.move_up()

if self.pressed["s"]: self.p1.move_down()

if self.pressed["o"]: self.p2.move_up()

if self.pressed["l"]: self.p2.move_down()

self.p1.redraw()

self.p2.redraw()

self.root.after(10, self._animate)

def _set_bindings(self):

for char in ["w","s","o", "l"]:

self.root.bind("" % char, self._pressed)

self.root.bind("" % char, self._released)

self.pressed[char] = False

def _pressed(self, event):

self.pressed[event.char] = True

def _released(self, event):

self.pressed[event.char] = False

class Paddle():

def __init__(self, canvas, tag, color="red", x=0, y=0):

self.canvas = canvas

self.tag = tag

self.x = x

self.y = y

self.color = color

self.redraw()

def move_up(self):

self.y = max(self.y -2, 0)

def move_down(self):

self.y = min(self.y + 2, 400)

def redraw(self):

x0 = self.x - 10

x1 = self.x + 10

y0 = self.y - 20

y1 = self.y + 20

self.canvas.delete(self.tag)

self.canvas.create_rectangle(x0,y0,x1,y1,tags=self.tag, fill=self.color)

if __name__ == "__main__":

p = Playfield()

p.start()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值