0

I'm trying to display the image from the link the code below works and shows image as intended

from tkinter import *
from PIL import ImageTk,Image
import requests
from io import BytesIO

root = Tk()
root.title('Weather')
root.iconbitmap('icon.ico')
root.geometry("450x300")

image_link = requests.get('https://assets.weatherstack.com/images/wsymbols01_png_64/wsymbol_0006_mist.png')
my_img = ImageTk.PhotoImage(Image.open(BytesIO(image_link.content)))
image_link  =Label(root, image = my_img)
image_link.grid(row = 0, column = 0 )

root.mainloop()

but now i have to update my code a little bit and have to put this in a function

from tkinter import *
from PIL import ImageTk,Image
import requests
from io import BytesIO

root = Tk()
root.title('Weather')
root.iconbitmap('icon.ico')
root.geometry("450x300")

def image_func():
    image_link = requests.get('https://assets.weatherstack.com/images/wsymbols01_png_64/wsymbol_0006_mist.png')
    my_img = ImageTk.PhotoImage(Image.open(BytesIO(image_link.content)))
    image_label  =Label(root, image = my_img)
    image_label.grid(row = 0, column = 0 )

image_func()
root.mainloop()

the above doesn't shows the image so I tried to to put the image label inside a frame but that just shows the frame with nothing inside also the powershell or cmd doesn't show any error

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685

1 Answers1

0

All the objects you create inside the function are local. So these object are deleted when the function exits. You need a way to keep these object existing. For example by using global variables

from tkinter import *
from PIL import ImageTk,Image
import requests
from io import BytesIO

root = Tk()
root.title('Weather')
root.iconbitmap('icon.ico')
root.geometry("450x300")

my_img = None
image_label = None

def image_func():
    global my_img, image_label

    image_link = requests.get('https://assets.weatherstack.com/images/wsymbols01_png_64/wsymbol_0006_mist.png')
    my_img = ImageTk.PhotoImage(Image.open(BytesIO(image_link.content)))
    image_label  = Label(root, image = my_img)
    image_label.grid(row = 0, column = 0 )

image_func()

root.mainloop()

Another way could be returning the objects from the function and keep the returned values

from tkinter import *
from PIL import ImageTk, Image
import requests
from io import BytesIO

root = Tk()
root.title('Weather')
root.iconbitmap('icon.ico')
root.geometry("450x300")

def image_func():
        
    image_link = requests.get('https://assets.weatherstack.com/images/wsymbols01_png_64/wsymbol_0006_mist.png')
    my_img = ImageTk.PhotoImage(Image.open(BytesIO(image_link.content)))
    image_label = Label(root, image=my_img)
    image_label.grid(row=0, column=0)

    return my_img, image_label


my_img, image_label = image_func()

root.mainloop()
Mace
  • 1,355
  • 8
  • 13
  • thanks it did work but this code was a skimmed version of it there were other labels and buttons on it but all those work fine it was just the image that was having the problem rest was working fine so it did not occur to me that global would be the solution anyway thank you :) – sarfaraz saleem Oct 09 '20 at 09:29
  • 1
    @sarfarazsaleem The basic idea is to keep a reference to the image, so that it is not sweeped by the pythons garbage collector. You can even say `image_label.imag = my_img` or global my_img` or make a list and append to it. All you have to do is to keep a reference to the image – Delrius Euphoria Oct 09 '20 at 11:54