Я борюсь с canvas.move в симуляции небесной системы. Как я могу одновременно перемещать несколько объектов в определенном экземпляре Space? Думаю, мне нужно что-то сделать с идентификацией объектов тела. Но я не могу это узнать. Возможно, мне следует использовать повторяющиеся методы рисования и удаления вместо canvas.move? См. упрощенную версию кода ниже. У кого-то есть предложение? Большое спасибо
import tkinter as tk
class Space(tk.Frame):
def __init__(self, master, size, bg=None):
super().__init__(master)
frame = tk.Frame(master, border = 5)
frame.pack()
self.width, self.height = size[0], size[1]
self.canvas = tk.Canvas(frame,
width = self.width,
height = self.height,
borderwidth= 0,
highlightthickness= 0,
bg=bg)
self.canvas.pack()
def place_body(self, body):
x1, y1 = body.loc[0], body.loc[1]
x2, y2 = x1+body.size, y1+body.size
self.canvas.create_oval(x1,y1,x2,y2, fill=body.color)
def distance_step(self):
pass
def move_body(self, body):
# in stead of distance_step:
dx, dy = body.speed[0], body.speed[1]
self.canvas.move(body, dx, dy)
self.canvas.after(1, lambda: self.move_body(body))
class CelestialBody:
def __init__(self, name, size, mass, loc, speed, color = "white"):
self.name = name
self.size = size
self.mass = mass
self.loc = loc
self.speed = speed
self.color = color
def __repr__(self):
return f"{self.name}"
class App:
def __init__(self):
x, y = 1000, 800
size = (x,y)
space = Space(root,size, bg = 'black')
sun1_size = 30
sun1_mass = 10
sun1_loc = (700, 450)
sun1_speed = (-200,0)
sun2_size = 30
sun2_mass = 10
sun2_loc = (300, 350)
sun2_speed = (200,0)
sun1 = CelestialBody("sun1", sun1_size, sun1_mass, sun1_loc, sun1_speed, color = "yellow")
sun2 = CelestialBody("sun2", sun2_size, sun2_mass, sun2_loc, sun2_speed, color = "yellow")
space.place_body(sun1)
space.place_body(sun2)
space.move_body(sun1)
space.move_body(sun2)
print(sun1, sun2)
root.mainloop()
root = tk.Tk()
root.title('UNIVERSE')
app = App()```






Вам нужно отслеживать тег, возвращенный из canvas.create_oval(). Смотрите .tk_tag ниже. Мне пришлось замедлить вашу скорость, потому что объект немедленно покинул экран. Также обратите внимание: вместо dx, dy = body.speed[0], body.speed[1] можно просто dx, dy = body.speed.
import tkinter as tk
class Space(tk.Frame):
def __init__(self, master, size, bg=None):
super().__init__(master)
frame = tk.Frame(master, border=5)
frame.pack()
self.width, self.height = size
self.canvas = tk.Canvas(frame,
width=self.width,
height=self.height,
borderwidth=0,
highlightthickness=0,
bg=bg)
self.canvas.pack()
def place_body(self, body):
x1, y1 = body.loc
x2, y2 = x1 + body.size, y1 + body.size
body.tk_tag = self.canvas.create_oval(x1, y1, x2, y2, fill=body.color)
def distance_step(self):
pass
def move_body(self, body):
# in stead of distance_step:
dx, dy = body.speed
dx, dy = dx/100, dy/100
self.canvas.move(body.tk_tag, dx, dy)
self.canvas.after(1, lambda: self.move_body(body))
class CelestialBody:
def __init__(self, name, size, mass, loc, speed, color = "white"):
self.name = name
self.size = size
self.mass = mass
self.loc = loc
self.speed = speed
self.color = color
self.tk_tag = None
def __repr__(self):
return f"{self.name}"
class App:
def __init__(self):
x, y = 1000, 800
size = (x, y)
space = Space(root, size, bg='black')
sun1_size = 30
sun1_mass = 10
sun1_loc = (700, 450)
sun1_speed = (-200, 0)
sun2_size = 30
sun2_mass = 10
sun2_loc = (300, 350)
sun2_speed = (200, 0)
sun1 = CelestialBody("sun1", sun1_size, sun1_mass, sun1_loc, sun1_speed, color = "yellow")
sun2 = CelestialBody("sun2", sun2_size, sun2_mass, sun2_loc, sun2_speed, color = "yellow")
space.place_body(sun1)
space.place_body(sun2)
space.move_body(sun1)
space.move_body(sun2)
print(sun1, sun2)
root.mainloop()
root = tk.Tk()
root.title('UNIVERSE')
app = App()
Это работает. Теперь я понимаю, что вы можете использовать идентификатор объекта класса в качестве атрибута того же объекта. Большое спасибо, Гленн, Сьяак.