如何统计Tkinter幻灯片60分钟内每张图片的显示次数
需求说明
在树莓派端基于tkinter开发图片幻灯片展示程序时,需要新增周期统计逻辑:以程序连续运行60分钟为一个统计周期,统计周期内幻灯片每张图片的累计显示次数。
示例:若指定资源文件夹下共存放20张图片,单个统计周期结束后,需要输出这20张图片各自在tkinter窗体中实际加载展示的总次数。
原有实现代码
class gui: def __init__(self,mainWin): self.counter = 0 self.mainWin = mainWin self.mainWin.title("picture frame") self.frame = tk.Frame(mainWin) self.img = tk.Label(self.frame) self.frame.place(relheight = 0.85, relwidth = 0.9, relx = 0.05, rely = 0.05) self.img.pack() self.pic() def pic(self): self.pic_list = [] for name in glob.glob(r'image_path*'): val = name self.pic_list.append(val) self.image_list = enumerate(self.pic_list) if self.counter == len(self.pic_list) - 1: self.counter = 0 else: self.counter = self.counter + 1 self.file = self.pic_list[self.counter] self.load = Image.open(self.file) self.pic_width = self.load.size[0] self.pic_height = self.load.size[1] self.real_aspect = self.pic_width / self.pic_height self.cal_width = int(self.real_aspect * 800) self.load2 = self.load.resize((self.cal_width,800)) self.render = ImageTk.PhotoImage(self.load2) self.img.config(image = self.render) self.img.image = self.render root.after(5000,self.pic) root = tk.Tk() myprog = gui(root) root.mainloop()
修改方案
原有代码存在冗余逻辑:每次切换图片都会重新遍历文件夹加载图片列表,完全可以把图片列表扫描逻辑移到初始化阶段执行,减少不必要的IO开销。在此基础上新增统计逻辑只需要覆盖三个模块:
- 初始化阶段新增统计相关变量:用字典存储图片显示计数,图片路径作为key,初始值为0;记录统计周期的起始时间戳,设置单周期时长为3600秒(60分钟)
- 计数触发逻辑:等图片完成缩放、渲染、挂载到Label控件实际显示后,再给对应图片的计数+1,避免图片加载损坏导致的统计误差
- 周期校验逻辑:每次切换图片前先校验当前运行时长是否达到60分钟,达到后先输出当前周期的统计结果,再重置计数器和周期起始时间,进入下一个统计周期
修改后可直接运行的代码
import tkinter as tk from PIL import Image, ImageTk import glob import time class gui: def __init__(self,mainWin): self.counter = 0 self.mainWin = mainWin self.mainWin.title("picture frame") # 初始化统计相关变量 self.show_count = {} self.cycle_duration = 3600 # 单统计周期60分钟,单位秒 self.cycle_start_time = time.time() self.frame = tk.Frame(mainWin) self.img = tk.Label(self.frame) self.frame.place(relheight = 0.85, relwidth = 0.9, relx = 0.05, rely = 0.05) self.img.pack() # 初始化阶段一次性加载图片列表,避免每次切图重复扫描文件夹 self.pic_list = [] for name in glob.glob(r'image_path*'): self.pic_list.append(name) self.show_count[name] = 0 # 每张图片初始显示次数为0 if not self.pic_list: raise RuntimeError("指定路径下未找到匹配的图片文件") self.pic() def pic(self): # 校验是否达到统计周期阈值 current_run_time = time.time() - self.cycle_start_time if current_run_time >= self.cycle_duration: # 输出当前周期统计结果,需要持久化可替换为写入文件逻辑 print("=== 60分钟统计周期结束,图片显示次数如下 ===") for pic_path, count in self.show_count.items(): print(f"图片路径:{pic_path},显示次数:{count}") # 重置统计数据,开启下一周期 self.show_count = {k:0 for k in self.pic_list} self.cycle_start_time = time.time() # 切换图片索引 if self.counter == len(self.pic_list) - 1: self.counter = 0 else: self.counter = self.counter + 1 self.file = self.pic_list[self.counter] self.load = Image.open(self.file) self.pic_width = self.load.size[0] self.pic_height = self.load.size[1] self.real_aspect = self.pic_width / self.pic_height self.cal_width = int(self.real_aspect * 800) self.load2 = self.load.resize((self.cal_width,800)) self.render = ImageTk.PhotoImage(self.load2) self.img.config(image = self.render) self.img.image = self.render # 图片实际渲染完成后计数+1 self.show_count[self.file] += 1 root.after(5000,self.pic) if __name__ == "__main__": root = tk.Tk() myprog = gui(root) root.mainloop()
- 统计结果默认打印在控制台,如果需要持久化存储,把控制台打印部分的逻辑改成写入csv/txt文件即可。
- 精度说明:幻灯片切换间隔为5秒,周期判断在每次切图时执行,实际周期误差不会超过5秒,满足树莓派展示场景的使用需求。
内容的提问来源于stack exchange,提问作者Arjun Sagar
相关产品推荐
相关产品推荐

