python - python有没有办法在几秒钟后隐藏画布?
问题描述
我正在尝试绘制 4 个保持在屏幕上几秒钟然后消失的球体。在每个球体下方会出现一个计时器,显示在它消失之前缺少多少秒。问题是我在理论上设法做的事情是可行的,但没有出现在屏幕上。我究竟做错了什么?有没有办法做到这一点?抱歉英语可能很糟糕,但我正在使用谷歌翻译
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
来计算和显示时间。
我timer
使用参数运行seconds
,ball
因此每个计时器都有单独的时间变量,它知道以后要删除哪个球。
Timer
运行refresh_label
它也得到参数label
,所以每个人都timer
使用 own label
、 ownsecond
和 own 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()
推荐阅读
- sql - AWS Kinesis Firehose 流是否会覆盖表上的 LOCK
- jenkins - 如何在传递参数的同时有条件地构建其他项目?
- c++ - 通过函数更改数组值
- android - Xamarin CommunityToolkit - 旋转的视频记录
- python - 使用 kubernetes python cli 列出命名空间中的证书
- http - 尝试从已解析的原始 HTTP 请求发送请求时出现意外的 EOF
- jwt - PyJWT 在云服务器上运行时引发 jwt.InvalidToken
- python - Django - 用于同时更新多个对象之间的多个关系的表格形式
- wordpress - WooCommerce 在分类/属性片段中搜索 - 完全匹配问题
- css - 需要帮助清理 SVG 动画