Как удалить холст из Tkinter после показа окна

Я хочу создать строку в Tkinter, и после изменения высоты мне нужно удалить предыдущую строку и создать новую строку с новой высотой, это повторяющийся процесс.

Для этого я прочитал учебник по Tkinter для python и думаю, что метод After может быть полезен. Итак, я пишу свою идею, но это не очень хороший метод, и я не могу его реализовать. Кроме того, я искал событие Shown в Tkinter, но не нашел событие Shown в Tkinter для окна.

Вот мой предлагаемый код:

from tkinter import *
from tkinter import messagebox
import numpy as np
import random
window = Tk()
window.geometry("600x400+650+200")
window.resizable(0, 0)
window.title("Ball Balancing Game - QLearning")

canvas = Canvas()

def uptodate():
    canvas.delete(line1)
    line1 = canvas.create_line(100, 200, 500, h)



# for i in range(len(h) - 1):
#     for j in range(len(h) - 1):
#
#         line1 = canvas.create_line(100, h[i], 500, h[j])
#         line2 = canvas.create_line(100, h[i+1], 500, h[j+1])
#         # lines = canvas.create_line(0,0,600,400)
#         # balls = canvas.create_oval(200, 150, 230, 110, outline="gray", fill="gray", width=6)
#         canvas.pack(fill=BOTH, expand=1)
#         canvas.delete(line1)
#         window.update()
#         window.after()
#         canvas.delete(lines)
#         canvas.update()
#         lines.destroy()
#         i = w.create_line(xy, fill="red")

line = canvas.create_line(100, 200, 500, 200)
canvas.pack(fill=BOTH, expand=1)
window.after(1000, uptodate())
window.mainloop()

person Saeed Rahmani    schedule 05.07.2017    source источник
comment
есть ли причина для удаления и воссоздания вместо того, чтобы просто изменить существующую строку?   -  person Bryan Oakley    schedule 05.07.2017
comment
@BryanOakley Нет, нет. Я думаю лучше поменять. Это мой первый опыт работы с Tkinter. Каково ваше решение?   -  person Saeed Rahmani    schedule 05.07.2017


Ответы (2)


Не нужно удалять, вы можете обновить все строки:

import tkinter as tk
import random
import numpy as np

class App(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.frame = tk.Frame(self, background="bisque")
        self.frame.pack(side="top", fill="both", expand=True)
        self.canvas = tk.Canvas(self.frame)
        self.line = self.canvas.create_line(100, 100, 300, 200, fill="blue")
        self.canvas.pack(side="top", fill="both", expand=True)
        self.draw_line()

    def remove_line(self, line):
        self.canvas.delete(line)

    def get_h(self):
        h1 = [-1, -0.86, -0.71, -0.57, -0.43, -0.29, -0.14, 0, 0.14, 0.29,0.43, 0.57, 0.71, 0.86, 1]
        map_h = np.linspace(100, 300, 15)
        map_h = np.around(map_h, 3)
        map_h = map_h.tolist()
        rnd_h1 = map_h[h1.index(random.choice(h1))]
        rnd_h2 = map_h[h1.index(random.choice(h1))]

        return rnd_h1, rnd_h2

   def draw_line(self):
        rnd_h1, rnd_h2 = self.get_h()
        self.canvas.coords(self.line, 100, rnd_h1, 300, rnd_h2)
        self.after(1000, self.draw_line)


app = App()
app.mainloop()
person ParisaN    schedule 05.07.2017

Как упомянул Брайан, вы можете изменить элемент на своем холсте, используя методы itemconfig или coords (см. Изменение атрибутов объекта холста tkinter)

Затем, чтобы создать цикл анимации с помощью метода after, вам нужно позволить функции анимации вызывать себя несколько раз.

Пример:

введите здесь описание изображения

import tkinter as tk
import numpy as np

window = tk.Tk()

canvas = tk.Canvas(window, width=120, height=100)
canvas.pack(fill="both", expand=1)
line1 = canvas.create_line(30, 50, 100, 50, fill="red", width=2)
count = 0

def update():
    """ This function updates the line coordinates and calls itself 62 times """
    global count
    count += 1
    canvas.coords(line1, 30, 50, 100, 50 + 30*np.sin(count/5))
    if count <= 62:
        window.after(100, update)

# Start the animation
update()

# Launch the app
window.mainloop()
person Josselin    schedule 05.07.2017