首页 > 解决方案 > 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()

标签: pythonpython-3.xtkintertkinter-canvas

解决方案


你有两个问题。

第一:你同时创造和摧毁球,所以你看不到球。您必须使用after()运行功能,该功能将在几秒钟后删除球。您可以删除在线球,然后label.destroy()在几秒钟后删除标签。

第二:您展示了 4 个球,但您只有一个self.label和一个self.seconds,并且所有球都使用它们。每个球都需要自己label和自己seconds来计算和显示时间。

timer使用参数运行secondsball因此每个计时器都有单独的时间变量,它知道以后要删除哪个球。

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()

推荐阅读