【问题标题】:tkinter (python): assign class method to a keytkinter(python):将类方法分配给键
【发布时间】:2019-02-19 11:49:43
【问题描述】:

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

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

我还有一个问题:

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

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

谢谢!

【问题讨论】:

  • “不工作”是什么意思?球会朝错误的方向飞去吗?你有错误吗?
  • 小鸟按右箭头键没有反应,它只是摔倒了。但是,我没有收到错误消息
  • 好的,所以问题不在于绑定本身。这只是焦点之一。仅当具有绑定的小部件具有键盘焦点时,与键的绑定才有效。

标签: python tkinter canvas move tkinter-canvas


【解决方案1】:

你必须将右键绑定到类内的画布上,并将焦点设置在画布上:

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

【讨论】:

  • “你必须将右键绑定到类内的画布上。” 这不是真的。可以在类之外进行绑定。
  • 是的,你是对的,这是可能的;我认为这里更有意义。
  • 谢谢你,它正在工作!但是我必须改变什么,以便当我按下右键时鸟只向右移动一步(同时仍然向下移动)?现在结果是对角线运动......
  • 很高兴我能帮上忙。这只鸟沿对角线移动,因为重力将其拉下(每 200 毫秒更新一次位置);你必须停下来让这只鸟只能侧身走。试一试(你必须澄清你想要的鸟的确切行为),如果遇到麻烦再问另一个问题;我们很乐意再次为您提供帮助。
【解决方案2】:

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

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

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

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

首先,从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)

【讨论】:

  • 好吧,我想我的问题表述不够准确,抱歉。我希望小鸟按照以下方式移动:在每个时间间隔内,它应该自动向下移动定义的距离。当按下箭头键时,小鸟应该额外向右移动一步。所以问题是,如果你明白我的意思,我希望这两个动作发生在同一时间间隔内......
  • @Kubi:一切皆有可能。
猜你喜欢
  • 1970-01-01
  • 2015-02-24
  • 1970-01-01
  • 1970-01-01
  • 2017-07-13
  • 1970-01-01
  • 2021-08-14
  • 2016-11-30
相关资源
最近更新 更多