如何在Tkinter中实现画布项目的平滑移动



我正在尝试在Tkinter中处理键盘驱动的事件,这样我就可以在画布小部件周围移动对象。向上、向下、向左和向右都可以,但当我尝试将两个关键点编程在一起时,移动不是平滑的对角运动。此外,每当按下关键点时,对象都会移动,然后会有一个轻微的延迟,然后它会平稳地移动。我如何才能实现平稳的运动按下键的那一刻,我如何才能获得平稳的对角线运动?

这是迄今为止的代码:

from tkinter import *
x = 10
y = 10
a = 100
b = 100
def change_coord(event):
        if event.keysym == 'Up':
            canvas1.move(rect, 0,-5)
        if event.keysym == 'Up' and 'Right':
            canvas1.move(rect, 5,-5)
        if event.keysym == 'Up' and 'Left':
            canvas1.move(rect, -5,-5)
        if event.keysym == 'Down':
            canvas1.move(rect, 0,5)
        if event.keysym == 'Down' and 'Right':
            canvas1.move(rect, 5,5)
        if event.keysym == 'Down' and 'Left':
            canvas1.move(rect, -5,5)
        if event.keysym == 'Right':
            canvas1.move(rect, 5,0)
        if event.keysym == 'Left':
            canvas1.move(rect, -5,0)
window = Tk()
window.geometry("400x200")
#canvas and drawing
canvas1=Canvas(window, height = 200, width = 400)
canvas1.grid(row=0, column=0, sticky=W)
coord = [x, y, a, b]
rect = canvas1.create_rectangle(*coord, outline="#fb0", fill="#fb0")
#capturing keyboard inputs and assigning to function
window.bind_all('<Up>', change_coord)
window.bind_all('<Down>', change_coord)
window.bind_all('<Left>', change_coord)
window.bind_all('<Right>', change_coord)
window.mainloop()

非常感谢!

编辑:

谢谢你的建议。我一直在尝试实现一个动画循环,以解决按下箭头键后的轻微延迟,但现在被卡住了。我的NEW代码如下所示,但运行该程序不会导致画布项目移动。首先,动画循环的想法正确吗?其次,我在哪里调用"移动"函数来移动项目。请帮忙——谢谢!

from tkinter import *
x = 10
y = 10
a = 100
b = 100
direction = None
def move():
    global x_vel
    global y_vel
    global direction
    if direction is not None:
        canvas1.move(rect, x_vel,y_vel)
        after(33,move)
def on_keypress(event):
    global direction
    global x_vel
    global y_vel
    if event.keysym == "Left":
        direction == "left"
        x_vel = -5
        y_vel = 0
    if event.keysym == "Right":
        direction == "right"
        x_vel = 5
        y_vel = 0
    if event.keysym == "Down":
        direction == "down"
        x_vel = 0
        y_vel = 5
    if event.keysym == "Up":
        direction == "up"
        x_vel = 0
        y_vel = -5
def on_keyrelease(event):
    global direction
    direction = None

window = Tk()
window.geometry("400x200")
#canvas and drawing
canvas1=Canvas(window, height = 200, width = 400)
canvas1.grid(row=0, column=0, sticky=W)
coord = [x, y, a, b]
rect = canvas1.create_rectangle(*coord, outline="#fb0", fill="#fb0")
#capturing keyboard inputs and assigning to function
window.bind_all('<KeyPress>', on_keypress)
window.bind_all('<KeyRelease>', on_keyrelease)
window.mainloop()

绑定到基本键是错误的方法。相反,绑定到按键按下和按键释放,并使用它们创建一个按键字典。每隔N毫秒,运行一个函数,该函数使用该字典来确定如何移动对象。(我不确定Tkinter计时器是否具有正确执行此操作所需的质量。)

如果程序失去焦点,一定要清除字典。

  1. 在on_keypress()函数内的if语句中,您使用==运算符而不是=运算符来设置方向。

  2. 在on_keypress()函数内设置方向后,您没有调用move()功能

这是您编辑和工作的代码。

注意:非常感谢您的代码。我在找这样的东西,你帮我节省了很多时间。我编辑了你的,来这里是为了给你,所以我们都修复了

from tkinter import *
x = 10
y = 10
a = 100
b = 100
direction = None
def move():
    global x_vel
    global y_vel
    global direction
    if direction is not None:
        canvas1.move(rect, x_vel,y_vel)
        after(33,move)
def on_keypress(event):
    global direction
    global x_vel
    global y_vel
    if event.keysym == "Left":
        direction = "left"
        x_vel = -5
        y_vel = 0
    if event.keysym == "Right":
        direction = "right"
        x_vel = 5
        y_vel = 0
    if event.keysym == "Down":
        direction = "down"
        x_vel = 0
        y_vel = 5
    if event.keysym == "Up":
        direction = "up"
        x_vel = 0
        y_vel = -5
    
    move()
def on_keyrelease(event):
    global direction
    direction = None

window = Tk()
window.geometry("400x200")
#canvas and drawing
canvas1=Canvas(window, height = 200, width = 400)
canvas1.grid(row=0, column=0, sticky=W)
coord = [x, y, a, b]
rect = canvas1.create_rectangle(*coord, outline="#fb0", fill="#fb0")
#capturing keyboard inputs and assigning to function
window.bind_all('<KeyPress>', on_keypress)
window.bind_all('<KeyRelease>', on_keyrelease)
window.mainloop()

最新更新