Displaying images from url in tkinter

11,488

http://effbot.org/pyfaq/why-do-my-tkinter-images-not-appear.htm provides an explanation.

When you add a PhotoImage or other Image object to a Tkinter widget, you must keep your own reference to the image object. If you don’t, the image won’t always show up.

The problem is that the Tkinter/Tk interface doesn’t handle references to Image objects properly; the Tk widget will hold a reference to the internal object, but Tkinter does not.

So something like this,

images = []

for i in range(0, 8):
    ...
    raw_data = urllib.request.urlopen(cover).read()
    im = Image.open(io.BytesIO(raw_data))
    image = ImageTk.PhotoImage(im)
    label1 = Label(mainWindow, image=image)
    label1.grid(row=i, sticky=W)

    # append to list in order to keep the reference
    images.append(image)
mainWindow.mainloop()
Share:
11,488
PotatoBox
Author by

PotatoBox

Updated on June 04, 2022

Comments

  • PotatoBox
    PotatoBox almost 2 years

    As title says, I want to display image from url, without downloading. My code so far:

    from bs4 import BeautifulSoup as soup
    from tkinter import *
    import urllib.parse
    from PIL import Image, ImageTk
    import io
    
    website = "http://www.porcys.com/review/"
    openWebsite = soup(urllib.request.urlopen(website), 'html.parser')
    
    reviews = openWebsite.find(name="section", attrs={'class': 'slider-content review'}).ul
    
    results = []
    for a in reviews(href=True):
        temp = "http://www.porcys.com"+a['href']
        results.append(temp)
    
    mainWindow = Tk()
    mainWindow.title("Latest Porcys reviews")
    
    for i in range(0, 8):
        review = results[i]
        openReview = soup(urllib.request.urlopen(review), 'html.parser')
        rating = openReview.find(name="span", attrs={'class': 'rating'})
        album = openReview.find(name="div", attrs={'class': 'wrapper'}).i
        artist = openReview.find(name="div", attrs={'class': 'wrapper'}).h2
        coverWIP = openReview.find(name="img", attrs={'class': 'cover'})
        for tag in openReview.find_all('i'):
            tag.replaceWith(' ')
        print(artist.text)
        print(album.text)
        print(rating.text)
        cover = "http://www.porcys.com"+coverWIP['src']
        print(cover)
        artistAndAlbum = Label(font=("Helvetica",10), text=artist.text+'- '+album.text)
        artistAndAlbum.grid(row=i, column=100, sticky=W)
        ratingGUI = Label(font=("Helvetica",10), text=rating.text)
        ratingGUI.grid(row=i+1,columnspan=100)
        raw_data = urllib.request.urlopen(cover).read()
        im = Image.open(io.BytesIO(raw_data))
        image = ImageTk.PhotoImage(im)
        label1 = Label(mainWindow, image=image)
        label1.grid(row=i, sticky=W)
        mainWindow.mainloop()
    

    "mainWindow.mainloop()" is causing troubles - when inside the loop, it shows only first image and after closing the widow, some errors are thrown. And when I put it outside the loop, it shows only last image. Also, I'm not sure if it's the most efficient way to display images.