Python 3 个 tkinter |来自 URL 的图片未显示

Python 3 tkinter | Image from URL not displaying

首先,我的代码是基于.

由于情况的原因,我试图将大部分代码打包到我调用的函数中 ImgFromUrl()

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

def ImgFromUrl(root, url):
    with urllib.request.urlopen(url) as connection:
        raw_data = connection.read()
    im = Image.open(io.BytesIO(raw_data))
    image = ImageTk.PhotoImage(im)
    return tk.Label(root, image=image)

root = tk.Tk()
url = "http://imgs.xkcd.com/comics/python.png"

widget = ImgFromUrl(root,url)
widget.grid(row=0,column=0)

root.mainloop()

由于某种原因,图像没有显示(尽管 Tkinter window 已自动调整为图像的大小)。

但是,这个有效:

# same imports

root = tk.Tk()
url = "http://imgs.xkcd.com/comics/python.png"

with urllib.request.urlopen(url) as connection:
    raw_data = connection.read()
im = Image.open(io.BytesIO(raw_data))
image = ImageTk.PhotoImage(im)

widget = tk.Label(root, image=image)
widget.grid(row=0,column=0)

root.mainloop()

所以你的问题是因为 image 在函数结束后立即被删除,tkinter 需要将图像保存在某处以供参考。

我们可以使用 global 或将图像返回到全局变量中定义的变量。

选项 1 global:

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


def ImgFromUrl(url):
    global image
    with urllib.request.urlopen(url) as connection:
        raw_data = connection.read()
    im = Image.open(io.BytesIO(raw_data))
    image = ImageTk.PhotoImage(im)
    return image

root = tk.Tk()
url = "http://imgs.xkcd.com/comics/python.png"
widget = tk.Label(root, image=ImgFromUrl(url))
widget.grid(row=0, column=0)

root.mainloop()

选项 2 将图像对象返回到全局命名空间中定义的变量:

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


def ImgFromUrl(url):
    with urllib.request.urlopen(url) as connection:
        raw_data = connection.read()
    im = Image.open(io.BytesIO(raw_data))
    image = ImageTk.PhotoImage(im)
    return image

root = tk.Tk()
url = "http://imgs.xkcd.com/comics/python.png"
image = ImgFromUrl(url)
widget = tk.Label(root, image=image)
widget.grid(row=0, column=0)

root.mainloop()