【问题标题】:Python tkinter image label randomly displays some images but not othersPython tkinter 图像标签随机显示一些图像但不显示其他图像
【发布时间】:2023-11-12 21:04:01
【问题描述】:

我有这个代码:

for imgTag in outputS:
    print(imgTag["src"])

root = tk.Tk()

for imgTag in outputS:
    url = imgTag["src"]
    with urllib.request.urlopen(url) as u:
        raw_data = u.read()
    im = Image.open(BytesIO(raw_data))
    image = ImageTk.PhotoImage(im)
    image.im = image
    label = tk.Label(root, image=image)
    label.pack( side = tk.BOTTOM)

root.mainloop()

它在命令行中生成:

http://images.sportinglife.com/racing/tsilks/92913.png
http://images.sportinglife.com/racing/tsilks/320898.png
http://images.sportinglife.com/racing/tsilks/6962.png
http://images.sportinglife.com/racing/tsilks/351124.png
http://images.sportinglife.com/racing/tsilks/239668.png
http://images.sportinglife.com/racing/tsilks/375038.png
http://images.sportinglife.com/racing/tsilks/201969.png
http://images.sportinglife.com/racing/tsilks/441.png
http://images.sportinglife.com/racing/tsilks/2384.png
http://images.sportinglife.com/racing/tsilks/363428.png
http://images.sportinglife.com/racing/tsilks/1828.png
http://images.sportinglife.com/racing/tsilks/226478.png
http://images.sportinglife.com/racing/tsilks/4966.png
http://images.sportinglife.com/racing/tsilks/375018.png
http://images.sportinglife.com/racing/tsilks/17484.png

但是,有些图像会显示在 tkinter 窗口中,而有些则不会。对于我拥有的每个 png 链接列表,似乎没有一个可辨别的模式被渲染到哪个不被渲染,尽管对于每个列表,总是会渲染相同的那些。例如:列表 1 = [1,2,3,4,5],列表 2 = [1,2,3,4,5]。列表 1 将始终渲染图像 1,3,4,列表 2 将始终渲染 2,3。

在我的另一个 python 文件中:

for x in range(0, num_horses):
    row1 = tk.Frame(root)
    row1.pack(side = tk.TOP)

    label = tk.Label(row1, text="horse " + str(x + 1))
    label.pack(side = tk.LEFT)

    imgTag = outputS[x]
    url = imgTag["src"]
    with urllib.request.urlopen(url) as u:
        raw_data = u.read()
    im = Image.open(BytesIO(raw_data))
    image = ImageTk.PhotoImage(im)
    image.im = image
    label = tk.Label(row1, image=image)
    label.pack( side = tk.LEFT)

    b1 = tk.Button(row1, text="back", command = lambda x=x: backHorse(x + 1))
    b1.pack( side = tk.LEFT )

    b2 = tk.Button(row1, text="lay", command = lambda x=x: layHorse(x + 1))
    b2.pack( side = tk.LEFT )

当它在与第一个 python 相同的链接列表上运行时,它们在渲染的图像方面会产生不同的结果,但对于应用程序来说它们总是相同的。例如:在列表 [1,2,3,4,5] 上,我在这篇文章中显示的第一个代码 sn-p 始终显示图像 1,2,4,第二个代码始终显示图像 2,5

【问题讨论】:

  • 你做了什么来调试这个?您是否验证过数据的大小大于零?您是否尝试过将数据保存到磁盘以验证图像数据是否可以被任何东西打开?

标签: python image url tkinter


【解决方案1】:

garbage collector 可能存在一些问题,这可能会删除 PhotoImage,因此您必须分配给变量。

但不是

image.im = image

这毫无意义。

你需要

label.im = image

适合我的完整版

import tkinter as tk
import urllib.request
from PIL import Image, ImageTk
from io import BytesIO

data = [
'http://images.sportinglife.com/racing/tsilks/92913.png',
'http://images.sportinglife.com/racing/tsilks/320898.png',
'http://images.sportinglife.com/racing/tsilks/6962.png',
'http://images.sportinglife.com/racing/tsilks/351124.png',
'http://images.sportinglife.com/racing/tsilks/239668.png',
'http://images.sportinglife.com/racing/tsilks/375038.png',
'http://images.sportinglife.com/racing/tsilks/201969.png',
'http://images.sportinglife.com/racing/tsilks/441.png',
'http://images.sportinglife.com/racing/tsilks/2384.png',
'http://images.sportinglife.com/racing/tsilks/363428.png',
'http://images.sportinglife.com/racing/tsilks/1828.png',
'http://images.sportinglife.com/racing/tsilks/226478.png',
'http://images.sportinglife.com/racing/tsilks/4966.png',
'http://images.sportinglife.com/racing/tsilks/375018.png',
'http://images.sportinglife.com/racing/tsilks/17484.png',
]

root = tk.Tk()

for url in data:

    with urllib.request.urlopen(url) as u:
        raw_data = u.read()

    image = Image.open(BytesIO(raw_data))
    photo = ImageTk.PhotoImage(image)

    label = tk.Label(root, image=photo)
    label.photo = photo
    label.pack()

root.mainloop()

顺便说一句:当您在函数或类中创建 PhotoImage 时,通常会出现问题,但在 for 循环中可能存在相同的问题。

http://effbot.org/tkinterbook/photoimage.htm

【讨论】:

  • 谢谢,这行得通。 image.im 和 label.im 有什么区别? .im 是什么?
  • image.im = image 中,您将PhotoImage 分配给同一PhotoImage 内的变量。有一些错误,garbage collector 有时会破坏PhotoImage - 所以它会破坏image 并且它也会自动破坏image.im(因为它是image 的一部分)。 im 是您自己的变量 - 您可以使用任何名称。我使用photo。如果您分配给label.imnon-PhotoImage 对象中的任何变量,那么它不会破坏label.im