tkinter (python): 将 class 方法分配给一个键

tkinter (python): assign class method to a key

在我的简单代码中,一个红球沿直线下落(有效)。当我按下右箭头键时,我希望球也向右移动。但是,这不起作用。我做错了什么?

from tkinter import *

root = Tk()

canvas = Canvas(root, height=400, width=500, background='black')
canvas.pack()


class Bird:
    def __init__(self, canvas, coords):
        self.canvas = canvas
        self.coords = coords
        self.bird = canvas.create_rectangle(coords, fill='red')

    def gravity(self):
        self.canvas.move(self.bird, 0, 10)
        self.canvas.after(200, self.gravity)

    def moveRight(self, event):
        self.canvas.move(self.bird, 10, 0)
        self.canvas.after(200, self.moveRight)

bird = Bird(canvas, (100, 100, 110, 110))

bird.gravity()

canvas.bind('<Right>', bird.moveRight)

root.mainloop()

我还有一个问题:

是否可以为整个 canvas 调用此 "after" 函数或类似函数,而不是分别调用这两种方法?

如果您发现我的代码有任何其他缺陷,请告诉我!

谢谢!

必须在class里面的canvas绑定右键,把焦点放在canvas:

from tkinter import *

root = Tk()

canvas = Canvas(root, height=400, width=500, background='black')
canvas.pack()


class Bird:
    def __init__(self, canvas, coords):
        self.canvas = canvas
        self.coords = coords
        self.bird = canvas.create_rectangle(coords, fill='red')
        self.canvas.bind('<Right>', self.moveRight)
        self.canvas.focus_set()

    def gravity(self):
        self.canvas.move(self.bird, 0, 10)
        self.canvas.after(200, self.gravity)

    def moveRight(self, event=None):
        self.canvas.move(self.bird, 10, 0)
        self.canvas.after(200, self.moveRight)


bird = Bird(canvas, (100, 100, 110, 110))

bird.gravity()

root.mainloop()

您面临的问题是您正在绑定键盘事件,但只有当具有绑定的小部件具有键盘焦点时,这些事件才能起作用。您可以使用 focus_set():

为 canvas 提供键盘焦点
canvas = Canvas(root, height=400, width=500, background='black')
canvas.focus_set()

Is it possible to call this "after"-function or a similar function for the whole canvas instead of the two methods separately?

是的。您的绑定可以调用您想要的任何函数。如果您希望拥有多个对象并且希望它们全部同时移动,则可以通过一个函数将它们全部移动。

首先,从 moveRight 中删除对 after 的调用。接下来,定义一个为每个对象调用 moveRight 的全局函数。例如:

def move_them_all():
    bird1.moveRight()
    bird2.moveRight()
    something_else.moveRight()
    self.canvas.after(1000, move_them_all)
...
canvas = Canvas(root, height=400, width=500, background='black')
...
canvas.bind('<right>', move_them_all)