В вашем коде много неправильного или любопытного. Во-первых, вы никогда не должны вызывать sleep
в программе, которая имеет цикл обработки событий. Когда вы звоните, вся ваша программа будет зависать. Если вы хотите, чтобы что-то произошло после определенного периода времени, используйте метод after
, чтобы запланировать выполнение функции в будущем.
Во-вторых, нет смысла звонить root.update
после звонка self.canvas.update_idletasks
. Например, предположим, что это каменное правило, которое никогда не следует называть update
. Можно позвонить update
, если вы знаете последствия этого, но так как вы только учитесь и не знаете, предположите, что это опасно называть. Кроме того, update
выполняет ту же работу, что и update_idletasks
и более, поэтому, если вы решите вызвать обновление, вызов update_idletasks
не требуется.
Что касается вашей реальной проблемы. Похоже, вы хотите создать два отдельных объекта «Box» и хотите скрыть и показать их независимо (?). Однако оба поля представляют собой прямоугольники, которые нарисованы на одном и том же холсте. Когда вы вызываете pack_forget
, это влияет на весь холст, поэтому оба этих объекта исчезают, а затем снова появляются.
Не ясно, каково ваше намерение. Если каждый экземпляр «Box» является просто прямоугольником на холсте, вы не хотите использовать pack_forget
, потому что это работает с виджетами, а не с объектами холста.
Если вы хотите, чтобы прямоугольники появлялись и исчезали, у вас есть несколько вариантов. Вы можете уничтожать и воссоздавать их каждый раз, или вы можете использовать метод canvas move
или coords
, чтобы переместить элемент в невидимую часть холста. Вы также можете управлять порядком наложения, чтобы поднять или опустить объект выше или ниже любого или всех других объектов.
Вот краткий пример, который использует способ перемещения предметов за пределы видимой области холста.
from Tkinter import *
import time
class Box:
def __init__(self, canvas, type):
self.canvas = canvas
if type == "1":
self.rect = canvas.create_rectangle(0, 0, 50, 50, fill="red")
elif type == "2":
self.rect = canvas.create_rectangle(50, 50, 100, 100, fill="blue")
self.coords = canvas.coords(canvas, self.rect)
def hide(self):
# remember where this object was
self.coords = canvas.coords(self.rect)
# move it to an invisible part of the canvas
self.canvas.move(self.rect, -1000, -1000)
def unhide(self):
# restore it to where it was
self.canvas.coords(self.rect, *self.coords)
root = Tk()
frame = Frame(root)
frame.pack()
canvas = Canvas(frame, width=500, height=200)
canvas.pack()
a = Box(canvas, type="1")
b = Box(canvas, type="2")
root.after(1000, a.hide)
root.after(2000, a.unhide)
root.after(3000, b.hide)
root.after(4000, b.unhide)
root.mainloop()
Наконец, если вы действительно хотите, чтобы объект непрерывно мигал, вы можете использовать метод hide
для автоматического вызова метода unhide
и наоборот:
def hide(self):
# remember where this object was
self.coords = canvas.coords(self.rect)
# move it to an invisible part of the canvas
self.canvas.move(self.rect, -1000, -1000)
# unhide after a second
self.canvas.after(1000, self.unhide)
def unhide(self):
# restore it to where it was
self.canvas.coords(self.rect, *self.coords)
# re-hide after a second
self.canvas.after(1000, self.hide)