在后台运行并与其他功能交互的倒计时计时器



我一直在四处寻找,但所有的解决方案都非常复杂,即使在那时,我也无法让它按我想要的方式运行。我正在制作一个程序,从文件夹中随机打开一个图像,等待10秒,然后从同一文件夹中打开另一个随机图像,然后继续运行。

很简单,我能够在While True循环中完成它,并制作";等待10秒";与时间分开。睡眠(10(。但是,我希望有一个按钮,只要我想,就可以简单地重置它。我在tkinter中这样做,我有一个启动它的按钮,但当我添加了一个重置它的按钮时,我无法点击它,当我尝试时,程序崩溃了。那是因为它在时间里。睡眠(10(,整个程序会停止10秒。对于任何对代码感兴趣的人来说,它就在这里。

from tkinter import *
import random
import os
from PIL import Image
import time
root = Tk()
def AnmuViewer():
while True:
random_pic = (random.choice(os.listdir("D:/de_clutter/memez/anmu")))
openPic = Image.open('D:/de_clutter/memez/anmu/' + random_pic)
openPic.show()
time.sleep(10)
continue
def Restart():
AnmuViewer()
start_btn = Button(root, text = "Start", command = AnmuViewer)
start_btn.pack()
next_btn = Button(root, text = 'Restart', command = Restart)
next_btn.pack()
root.mainloop()

我知道我不需要;重新启动";按钮能够点击";启动";按钮也会做同样的事情。不管怎样;启动";按钮本身也是可松开的。

我研究过线程,所以我想做一个从10开始倒计时的函数,当它达到10时,AnmuViewer()会重新开始,这样我就可以点击";启动";无论何时再次,并从头开始重置整个代码。但我也没能让它发挥作用。有什么建议吗?

您可以将startreset组合在同一个按钮中,但也可以添加一个调用相同函数的重置按钮(注释代码(。也就是说,在启动时,系统被重置到其初始状态,这里callback值被设置为None

大多数情况下,使用tkinter.mainloop比使用自定义while循环要好。在GUI中使用time.sleep通常会带来灾难,因为它在执行过程中会阻塞所有交互。

为了简单起见,我用text label替换了这些图像,您必须更改它。

import tkinter as tk
import random

def anmu_viewer():
global cb
random_pic = random.choice(images)
lbl.config(text=random_pic)
cb = root.after(10000, anmu_viewer)   # keep a reference of the callback
def reset():
global cb
if cb is not None:
root.after_cancel(cb)             # cancel the callback
cb = None                         # reset the reference to the callback to None
anmu_viewer()

images = ['im1', 'im2', 'im3', 'im4', 'im5', 'im6']
root = tk.Tk()
cb = None    
lbl = tk.Label(root, text='')
lbl.pack()
start_btn = tk.Button(root, text="Start", command=reset)
start_btn.pack()
# reset_btn = tk.Button(root, text="Reset", command=reset)
# reset_btn.pack()
root.mainloop()

while与tkinter一起使用会导致mainloop()出现一些问题,并将冻结该问题。您应该使用after(ms,func),它不会冻结GUI。一个非常简单的代码可以做到这一点,看看这里:

from tkinter import *
from tkinter import filedialog
from PIL import ImageTk, Image
from glob import glob #for the path of the image
import random
root = Tk()
def anmuViewer():
global cb
choice = random.choice(all_img) #random choice of image from the list of img
cur = ImageTk.PhotoImage(file=choice) #make an image object
img_label.config(image=cur) #changing the image on the label
img_label.img = cur #keeping a reference to the image
cb = root.after(10000,anmuViewer) #repeating the function every 10 second
def restart(): #reset func from Roblochons code
global cb
if cb is not None:
root.after_cancel(cb)
cb = None
anmuViewer()
path = filedialog.askdirectory(title='Choose the directory with images') #ask the directory with the image.
png = glob(path+'/*.png') #pick all the png image
jpg = glob(path+'/*.jpg') #pick all the jpg image
all_img = png + jpg #concatenate both the list
img_label = Label(root) #image label, later to be configured
img_label.pack()
start_btn = Button(root, text = "Start", command=anmuViewer)
start_btn.pack(padx=10,pady=10)
next_btn = Button(root, text = 'Restart', command=restart)
next_btn.pack(padx=10,pady=10)
root.mainloop()

我已经用注释解释了代码,所以在旅途中更容易理解。我还没有假设你有什么路径的图像,所以我选择的路径是动态的,正如你所看到的。代码看起来很长,因为我简化了大部分代码行以便更好地理解。

无论如何,你需要调整图像的大小,使其适合每个人的屏幕,因为像素和屏幕分辨率因设备而异。看看这里

最新更新