Python3使用Tkinter制作图片幻灯片无法显示目录图片求助
问题描述
- 运行环境:Ubuntu 20.04 LTS
- 实现方案:使用Python3搭配Tkinter开发图片幻灯片程序,依赖PIL、random、glob库
- 故障现象:程序运行无报错,但无法正常显示指定目录下存储的图片
原实现代码:
import tkinter as Tk from PIL import Image, ImageTk import random import glob class gui: def __init__(self, mainwin): self.counter = 0 self.mainwin = mainwin self.mainwin.title("Our Photos") self.colour() self.mainwin.configure(bg = "yellow") 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 colour(self): self.colours =['gray47','gray48'] c = random.choice(self.colours) self.mainwin.configure(bg = c) root.after(4000, self.colour) def pic(self): for name in glob.glob(r"/home/maheswar/Pictures/*"): self.pic_list = [] val = name self.pic_list.append(val) 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.calc_width = int(self.real_aspect * 800) self.load2 = self.load.resize((self.calc_width, 800)) self.render = ImageTk.PhotoImage(self.load2) self.img.config(image = self.render) self.img.image = self.render root.after(2000, self.pic) root = Tk.Tk() myprog = gui(root) root.geometry("1000x1000") root.mainloop()
故障根因
代码存在3个核心逻辑错误,直接导致图片无法正常轮播显示:
- 图片列表逻辑错误:
pic()方法的for循环中,每次遍历文件都会执行self.pic_list = []清空列表,最终列表里只会保留最后一个遍历到的文件,没有存储全量图片路径;且没有过滤非图片格式,一旦遍历到目录、其他格式文件,Image.open会直接触发异常导致加载中断 - 计数器逻辑错误:计数器递增的代码写的是
self.counter == self.counter + 1,这里用了比较运算符==而不是赋值运算符=,计数器永远停在初始值0,不会正常递增 - 重复扫描目录:每2秒轮播一次就会重新扫描一次整个图片目录,属于冗余操作,且如果目录下文件变动会直接导致列表长度和计数器不匹配,触发索引越界
另外存在显示适配问题:缩放图片时固定按800高度计算宽度,没有判断计算出的宽度是否超出窗口可用宽度,会导致图片超出Frame范围无法正常显示。
修复后代码
import tkinter as Tk from PIL import Image, ImageTk import random import glob class gui: def __init__(self, mainwin): self.counter = 0 self.mainwin = mainwin self.mainwin.title("Our Photos") # 初始化时一次性扫描目录,过滤常见图片格式 self.pic_list = [] img_suffix = ('.jpg', '.jpeg', '.png', '.bmp', '.gif') for path in glob.glob(r"/home/maheswar/Pictures/*"): if path.lower().endswith(img_suffix): self.pic_list.append(path) # 无图片时直接给出提示 if not self.pic_list: print("指定目录下未找到可用图片") return self.mainwin.configure(bg = "yellow") 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.colour() self.pic() def colour(self): self.colours =['gray47','gray48'] c = random.choice(self.colours) self.mainwin.configure(bg = c) # 用实例持有的窗口对象替代全局root self.mainwin.after(4000, self.colour) def pic(self): # 循环重置计数器 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.pic_height = self.load.size self.real_aspect = self.pic_width/self.pic_height # 固定高度800计算宽度,超出可用宽度900时改为按宽度适配 self.calc_width = int(self.real_aspect * 800) if self.calc_width > 900: self.calc_width = 900 calc_height = int(self.calc_width / self.real_aspect) self.load2 = self.load.resize((self.calc_width, calc_height)) else: self.load2 = self.load.resize((self.calc_width, 800)) self.render = ImageTk.PhotoImage(self.load2) self.img.config(image = self.render) self.img.image = self.render self.mainwin.after(2000, self.pic) root = Tk.Tk() myprog = gui(root) root.geometry("1000x1000") root.mainloop()
关键修改说明
- 图片扫描逻辑移到类初始化方法中,程序启动仅扫描一次目录,同时过滤非图片文件,避免无效加载
- 修复计数器运算符错误,保证轮播索引正常递增
- 移除循环内重复清空图片列表的错误逻辑,正确存储全量图片路径
- 增加图片尺寸适配判断,避免图片超出容器范围无法显示
- 替换方法内对全局
root的直接引用,改用实例持有的mainwin对象,避免全局变量依赖问题 - 增加空图片目录提示,目录无图片时直接给出终端提示,避免无意义运行
内容的提问来源于stack exchange,提问作者mahiatlinux
相关产品推荐
相关产品推荐

