tkinter непрерывно перемещает объект с помощью таймера в Canvas

#python #tkinter

#python #tkinter

Вопрос:

Я хочу переместить объект и прокрутить окно canvas для непрерывного следования за объектом с помощью 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 клавиши), а вторая, move_after(object) которая перемещает объект с помощью after (в примере активируется нажатием arrow_right клавиши).
Проблема в том, что с первой функцией, когда объект начинает двигаться, он тоже начинает вибрировать, в то время как со второй функцией перемещение объекта выполняется правильно. Я не понимаю, почему объект вибрирует, когда я использую функцию таймера, мне нужно использовать ее, чтобы не перегружать основной цикл.
Я работаю над Windows 10 с Python 3

Ответ №1:

Он вибрирует, потому что 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))
  

Комментарии:

1. у меня это не работает, он все еще вибрирует, в любом случае я бы не хотел менять значения x_movement и y_movement , я думаю, должно быть лучшее решение. Кстати, в коде u вызываются оба master.after(30, lambda: move_after(object)) и Timer(30/1000, lambda: move_Timer(object,y)) .

2. ops Я допустил ошибку, вы можете удалить master.after(30, lambda: move_after(object)), для меня в любом случае это работает.