You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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个核心逻辑错误,直接导致图片无法正常轮播显示:

  1. 图片列表逻辑错误:pic()方法的for循环中,每次遍历文件都会执行self.pic_list = []清空列表,最终列表里只会保留最后一个遍历到的文件,没有存储全量图片路径;且没有过滤非图片格式,一旦遍历到目录、其他格式文件,Image.open会直接触发异常导致加载中断
  2. 计数器逻辑错误:计数器递增的代码写的是self.counter == self.counter + 1,这里用了比较运算符==而不是赋值运算符=,计数器永远停在初始值0,不会正常递增
  3. 重复扫描目录:每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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 06:48:24