Vamp
Vamp

Reputation: 95

How do I display an Image (from URL) in Tkinter

I want to display an image from a URL in Tkinter. This is my current function:

def getImageFromURL(url):
    print('hai')
    raw_data = urlopen(url).read()
    im = Image.open(BytesIO(raw_data))
    image = ImageTk.PhotoImage(im)
    return image

And the code where I am using this function is:

print(imgJSON[currentIndex])
img = getImageFromURL(imgJSON[currentIndex])
imagelab = tk.Label(self, image=img)
imagelab.image = img
imagelab.pack()

However, the code is making the tkinter window crash (Not Responding), but there are no errors. How would I fix this?

Upvotes: 1

Views: 1099

Answers (1)

acw1668
acw1668

Reputation: 46688

You can use thread to fetch the image from internet and use tkinter virtual event to notify the tkinter application when the image has been loaded.

Below is an example code:

import threading
import tkinter as tk
from urllib.request import urlopen
from PIL import ImageTk

def getImageFromURL(url, controller):
    print('hai')
    try:
        controller.image = ImageTk.PhotoImage(file=urlopen(url))
        # notify controller that image has been downloaded
        controller.event_generate("<<ImageLoaded>>")
    except Exception as e:
        print(e)

class App(tk.Tk):
    def __init__(self):
        super().__init__()

        self.imagelab = tk.Label(self, text="Loading image from internet ...", width=50, height=5)
        self.imagelab.pack()

        self.bind("<<ImageLoaded>>", self.on_image_loaded)

        # start a thread to fetch the image
        url = "https://batman-news.com/wp-content/uploads/2017/11/Justice-League-Superman-Banner.jpg"
        threading.Thread(target=getImageFromURL, args=(url, self)).start()

    def on_image_loaded(self, event):
        self.imagelab.config(image=self.image, width=self.image.width(), height=self.image.height())

App().mainloop()

Upvotes: 1

Related Questions