Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Displaying images from url in tkinter [duplicate]

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.

like image 548
PotatoBox Avatar asked Sep 16 '25 10:09

PotatoBox


1 Answers

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()
like image 70
J.J. Hakala Avatar answered Sep 19 '25 05:09

J.J. Hakala