python 中有没有办法在几秒钟后隐藏 canvas?
is there a way in python to hide canvas after few second?
我正在尝试绘制 4 个球体,这些球体会在屏幕上停留几秒钟然后消失。每个球体下方都会出现一个计时器,显示在它消失前还剩多少秒。问题是我在理论上设法做到的是可行的,但没有按应有的方式出现在屏幕上。
我究竟做错了什么?有没有办法做到这一点?
抱歉,英语可能很糟糕,但我正在使用 google 翻译
import tkinter as tk
from tkinter import Tk, Frame, Canvas, BOTH
class Draw(Frame):
def __init__(self, parent):
super().__init__()
self.initUI()
def initUI(self):
self.pack(fill=BOTH, expand=1)
canvas = Canvas(self)
heightpx=Tk.winfo_screenheight(self)
widthpx=Tk.winfo_screenwidth(self)
distOrizPx=int(widthpx/4)
distVertPx=int(heightpx/4)
radiusPx=50
self.ball01 = canvas.create_oval(distOrizPx-radiusPx, distVertPx-radiusPx, distOrizPx+radiusPx, distVertPx+radiusPx, fill="blue", width=0)
self.ball02 = canvas.create_oval(widthpx-distOrizPx-radiusPx, distVertPx-radiusPx, widthpx-distOrizPx+radiusPx, distVertPx+radiusPx, fill="red", width=0)
self.ball03 = canvas.create_oval(distOrizPx-radiusPx, heightpx-distVertPx-radiusPx, distOrizPx+radiusPx, heightpx-distVertPx+radiusPx, fill="green", width=0)
self.ball04 = canvas.create_oval(widthpx-distOrizPx-radiusPx, heightpx-distVertPx-radiusPx, widthpx-distOrizPx+radiusPx, heightpx-distVertPx+radiusPx, fill="yellow", width=0)
canvas.pack(fill=BOTH, expand=1)
self.timer(distOrizPx-radiusPx, distVertPx+radiusPx)
canvas.delete(self.ball01)
self.timer(widthpx-distOrizPx-radiusPx, distVertPx+radiusPx)
canvas.delete(self.ball02)
self.timer(distOrizPx-radiusPx, heightpx-distVertPx+radiusPx)
canvas.delete(self.ball03)
self.timer(widthpx-distOrizPx-radiusPx, heightpx-distVertPx+radiusPx)
canvas.delete(self.ball04)
def timer(self,posx,posy):
self.seconds = 3
self.label= tk.Label(text="%i s" % self.seconds, font="Arial 30")
self.label.place(x=posx, y=posy)
self.label.after(1000, func=self.refresh_label())
def refresh_label(self):
self.seconds -= 1
self.label.configure(text="%i s" % self.seconds)
if self.seconds>-1:
self.label.after(1000, self.refresh_label)
elif self.seconds==-1:
self.label.destroy()
class Ball:
def __init__(self, master):
master.title("Ball")
master.geometry("200x200")
master.state('zoomed')
self.master = master
self.draw = Draw(master)
if __name__ == "__main__":
master = tk.Tk()
pyBall = Ball(master)
master.mainloop()
你有两个问题。
首先:你同时创建和销毁球,所以你看不到球。你必须使用 after()
到 运行 函数,它会在几秒钟后删除球。您可以在 label.destroy()
之后删除行中的球,这会在几秒后删除标签。
其次: 你展示了 4 个球,但你只有一个 self.label
和一个 self.seconds
,而且所有的球都使用它们。每个球需要拥有label
和拥有seconds
来计算和显示时间。
I 运行 timer
带有参数 seconds
和 ball
所以每个计时器都有时间变量,它知道以后要删除哪个球。
Timer
运行s refresh_label
也得到参数 label
所以每个 timer
使用自己的 label
, 自己的 second
,并拥有 ball
.
import tkinter as tk
from tkinter import Tk, Frame, Canvas, BOTH
class Draw(Frame):
def __init__(self, master):
super().__init__(master)
self.initUI()
def initUI(self):
self.pack(fill=BOTH, expand=1)
self.canvas = Canvas(self, bg='red')
self.canvas.pack(fill=BOTH, expand=1)
heightpx = Tk.winfo_screenheight(self)
widthpx = Tk.winfo_screenwidth(self)
distOrizPx = int(widthpx/4)
distVertPx = int(heightpx/4)
radiusPx = 50
self.ball01 = self.canvas.create_oval(distOrizPx-radiusPx, distVertPx-radiusPx, distOrizPx+radiusPx, distVertPx+radiusPx, fill="blue", width=1)
self.ball02 = self.canvas.create_oval(widthpx-distOrizPx-radiusPx, distVertPx-radiusPx, widthpx-distOrizPx+radiusPx, distVertPx+radiusPx, fill="red", width=0)
self.ball03 = self.canvas.create_oval(distOrizPx-radiusPx, heightpx-distVertPx-radiusPx, distOrizPx+radiusPx, heightpx-distVertPx+radiusPx, fill="green", width=0)
self.ball04 = self.canvas.create_oval(widthpx-distOrizPx-radiusPx, heightpx-distVertPx-radiusPx, widthpx-distOrizPx+radiusPx, heightpx-distVertPx+radiusPx, fill="yellow", width=0)
self.timer(distOrizPx-radiusPx, distVertPx+radiusPx, 17, self.ball01)
self.timer(widthpx-distOrizPx-radiusPx, distVertPx+radiusPx, 7, self.ball02)
self.timer(distOrizPx-radiusPx, heightpx-distVertPx+radiusPx, 7, self.ball03)
self.timer(widthpx-distOrizPx-radiusPx, heightpx-distVertPx+radiusPx, 13, self.ball04)
def timer(self, posx, posy, seconds, ball):
label = tk.Label(self, text="%i s" % seconds, font="Arial 30")
label.place(x=posx, y=posy)
label.after(1000, self.refresh_label, label, seconds, ball)
def refresh_label(self, label, seconds, ball):
seconds -= 1
label.configure(text="%i s" % seconds)
if seconds >= 0:
label.after(1000, self.refresh_label, label, seconds, ball)
elif seconds < 0:
label.destroy()
self.canvas.delete(ball)
class Ball:
def __init__(self, master):
master.title("Ball")
master.geometry("1200x1200")
#master.state('zoomed')
self.master = master
self.draw = Draw(master)
if __name__ == "__main__":
master = tk.Tk()
pyBall = Ball(master)
master.mainloop()
我正在尝试绘制 4 个球体,这些球体会在屏幕上停留几秒钟然后消失。每个球体下方都会出现一个计时器,显示在它消失前还剩多少秒。问题是我在理论上设法做到的是可行的,但没有按应有的方式出现在屏幕上。 我究竟做错了什么?有没有办法做到这一点? 抱歉,英语可能很糟糕,但我正在使用 google 翻译
import tkinter as tk
from tkinter import Tk, Frame, Canvas, BOTH
class Draw(Frame):
def __init__(self, parent):
super().__init__()
self.initUI()
def initUI(self):
self.pack(fill=BOTH, expand=1)
canvas = Canvas(self)
heightpx=Tk.winfo_screenheight(self)
widthpx=Tk.winfo_screenwidth(self)
distOrizPx=int(widthpx/4)
distVertPx=int(heightpx/4)
radiusPx=50
self.ball01 = canvas.create_oval(distOrizPx-radiusPx, distVertPx-radiusPx, distOrizPx+radiusPx, distVertPx+radiusPx, fill="blue", width=0)
self.ball02 = canvas.create_oval(widthpx-distOrizPx-radiusPx, distVertPx-radiusPx, widthpx-distOrizPx+radiusPx, distVertPx+radiusPx, fill="red", width=0)
self.ball03 = canvas.create_oval(distOrizPx-radiusPx, heightpx-distVertPx-radiusPx, distOrizPx+radiusPx, heightpx-distVertPx+radiusPx, fill="green", width=0)
self.ball04 = canvas.create_oval(widthpx-distOrizPx-radiusPx, heightpx-distVertPx-radiusPx, widthpx-distOrizPx+radiusPx, heightpx-distVertPx+radiusPx, fill="yellow", width=0)
canvas.pack(fill=BOTH, expand=1)
self.timer(distOrizPx-radiusPx, distVertPx+radiusPx)
canvas.delete(self.ball01)
self.timer(widthpx-distOrizPx-radiusPx, distVertPx+radiusPx)
canvas.delete(self.ball02)
self.timer(distOrizPx-radiusPx, heightpx-distVertPx+radiusPx)
canvas.delete(self.ball03)
self.timer(widthpx-distOrizPx-radiusPx, heightpx-distVertPx+radiusPx)
canvas.delete(self.ball04)
def timer(self,posx,posy):
self.seconds = 3
self.label= tk.Label(text="%i s" % self.seconds, font="Arial 30")
self.label.place(x=posx, y=posy)
self.label.after(1000, func=self.refresh_label())
def refresh_label(self):
self.seconds -= 1
self.label.configure(text="%i s" % self.seconds)
if self.seconds>-1:
self.label.after(1000, self.refresh_label)
elif self.seconds==-1:
self.label.destroy()
class Ball:
def __init__(self, master):
master.title("Ball")
master.geometry("200x200")
master.state('zoomed')
self.master = master
self.draw = Draw(master)
if __name__ == "__main__":
master = tk.Tk()
pyBall = Ball(master)
master.mainloop()
你有两个问题。
首先:你同时创建和销毁球,所以你看不到球。你必须使用 after()
到 运行 函数,它会在几秒钟后删除球。您可以在 label.destroy()
之后删除行中的球,这会在几秒后删除标签。
其次: 你展示了 4 个球,但你只有一个 self.label
和一个 self.seconds
,而且所有的球都使用它们。每个球需要拥有label
和拥有seconds
来计算和显示时间。
I 运行 timer
带有参数 seconds
和 ball
所以每个计时器都有时间变量,它知道以后要删除哪个球。
Timer
运行s refresh_label
也得到参数 label
所以每个 timer
使用自己的 label
, 自己的 second
,并拥有 ball
.
import tkinter as tk
from tkinter import Tk, Frame, Canvas, BOTH
class Draw(Frame):
def __init__(self, master):
super().__init__(master)
self.initUI()
def initUI(self):
self.pack(fill=BOTH, expand=1)
self.canvas = Canvas(self, bg='red')
self.canvas.pack(fill=BOTH, expand=1)
heightpx = Tk.winfo_screenheight(self)
widthpx = Tk.winfo_screenwidth(self)
distOrizPx = int(widthpx/4)
distVertPx = int(heightpx/4)
radiusPx = 50
self.ball01 = self.canvas.create_oval(distOrizPx-radiusPx, distVertPx-radiusPx, distOrizPx+radiusPx, distVertPx+radiusPx, fill="blue", width=1)
self.ball02 = self.canvas.create_oval(widthpx-distOrizPx-radiusPx, distVertPx-radiusPx, widthpx-distOrizPx+radiusPx, distVertPx+radiusPx, fill="red", width=0)
self.ball03 = self.canvas.create_oval(distOrizPx-radiusPx, heightpx-distVertPx-radiusPx, distOrizPx+radiusPx, heightpx-distVertPx+radiusPx, fill="green", width=0)
self.ball04 = self.canvas.create_oval(widthpx-distOrizPx-radiusPx, heightpx-distVertPx-radiusPx, widthpx-distOrizPx+radiusPx, heightpx-distVertPx+radiusPx, fill="yellow", width=0)
self.timer(distOrizPx-radiusPx, distVertPx+radiusPx, 17, self.ball01)
self.timer(widthpx-distOrizPx-radiusPx, distVertPx+radiusPx, 7, self.ball02)
self.timer(distOrizPx-radiusPx, heightpx-distVertPx+radiusPx, 7, self.ball03)
self.timer(widthpx-distOrizPx-radiusPx, heightpx-distVertPx+radiusPx, 13, self.ball04)
def timer(self, posx, posy, seconds, ball):
label = tk.Label(self, text="%i s" % seconds, font="Arial 30")
label.place(x=posx, y=posy)
label.after(1000, self.refresh_label, label, seconds, ball)
def refresh_label(self, label, seconds, ball):
seconds -= 1
label.configure(text="%i s" % seconds)
if seconds >= 0:
label.after(1000, self.refresh_label, label, seconds, ball)
elif seconds < 0:
label.destroy()
self.canvas.delete(ball)
class Ball:
def __init__(self, master):
master.title("Ball")
master.geometry("1200x1200")
#master.state('zoomed')
self.master = master
self.draw = Draw(master)
if __name__ == "__main__":
master = tk.Tk()
pyBall = Ball(master)
master.mainloop()