tkinter使用Canvas中的Timer连续移动对象

时间:2019-03-17 16:15:57

标签: python tkinter

我想移动一个对象,并滚动画布窗口,以便使用Timer模块中的threading函数连续跟随该对象, 这是一个可执行的示例

from tkinter import *
from threading import Timer

x_movement = 3
def move_Timer(object):
    canvas.move(object, x_movement, 0)
    canvas.xview_scroll(3, UNITS)
    Timer(30/1000, lambda: move_Timer(object)).start()


def move_after(object):
    canvas.move(object, x_movement, 0)
    canvas.xview_scroll(3, UNITS)
    master.after(30, lambda: move_after(object))


master = Tk()

canvas_width = 1000
canvas_height = 600
canvas_scrollregion_width = 3000
canvas_scrollregion_height = 3000
canvas = Canvas(master, width=canvas_width, height=canvas_height, bg="black")
canvas.configure(scrollregion=(0, 0, canvas_scrollregion_width,     canvas_scrollregion_height), yscrollincrement='1', xscrollincrement='1')
x = (master.winfo_screenwidth() / 2) - (canvas_width // 2)
y = (master.winfo_screenheight() / 2) - (canvas_height // 2)
master.geometry('%dx%d+%d+%d' % (canvas_width + 4, canvas_height + 4, x, y))
canvas.pack()

x1, y1 = canvas_scrollregion_width/2, canvas_scrollregion_height/2
ball = canvas.create_oval(x1, y1, x1 + 50, y1 + 50, fill="red")
canvas.xview_moveto((x1 - canvas_width/2)/canvas_scrollregion_width)
canvas.yview_moveto((y1 - canvas_height/2)/canvas_scrollregion_height)


master.bind("d", lambda event: move_Timer(ball))
master.bind('<Right>', lambda event: move_after(ball))
master.bind("<Button-1>", lambda event: print(canvas.canvasx(event.x),canvas.canvasy(event.y)))
master.mainloop()

在此示例中,有两个功能,第一个move_Timer(object)使用Timer移动对象(在该示例中,通过按下d键激活),第二个{{1 }}使用move_after(object)移动对象(在此示例中,通过按下after键激活了该对象)。 问题在于,使用第一个功能时,对象开始移动时,对象也开始振动;而使用第二个功能时,对象移动正确。我不明白为什么在使用Timer函数时对象会振动,所以我需要使用它来避免主循环过载。 我正在使用python 3在Windows 10上工作

1 个答案:

答案 0 :(得分:0)

它之所以振动,是因为x_movement永远不会改变,甚至y永远都不会改变。

为了说明这一点,我做了一些改动。

我介绍了y变量...;)

def move_Timer(object,y):
    canvas.move(object, x_movement, y)
    canvas.xview_scroll(3, UNITS)
    #master.after(30, lambda: move_after(object))
    y +=1
    t =Timer(30/1000, lambda: move_Timer(object,y))
    t.start()

甚至更改此行

master.bind("d", lambda event: move_Timer(ball,0))