I'm making a simple weather app in Custom Tkinter usimg OpenWeather's API, and I'm having trouble updating the weather icon when the user enters another city from the list. I'm still working on the app, excuse the messy code.
import requests
from customtkinter import *
from PIL import Image
app = CTk()
app.title('Turtle')
app.geometry('1000x500')
c_img = CTkImage(light_image=Image.open('cloudy.jpg'),size=(100, 100))
msg_label = CTkLabel(app, text="", text_color='Blue', font=('Arial', 25, 'bold'))
temp_label = CTkLabel(app, text="", text_color='Blue', font=('Arial', 25, 'bold'))
condition_label = CTkLabel(app, text="", text_color='Blue', font=('Arial', 25, 'bold'))
wind_label = CTkLabel(app, text="", text_color='Blue', font=('Arial', 25, 'bold'))
alert_label = CTkLabel(app, text="", text_color='Blue', font=('Arial', 25, 'bold'))
filename1 = "cloudy.jpg"
name_entry = CTkEntry(app, font=('Arial', 25, 'bold'), corner_radius=32)
ecity = ""
def update_weather(event):
filename1 = 'cloudy.jpg'
ecity = ""
ecity = name_entry.get()
#Fetch weather information from OpenWeatherMap API
api = '928c56960d62b32ac062752c50a07679'
cityid = '6094817'
if ecity.lower() == "mecca" :
cityid = '104515'
elif ecity.lower() == "medina":
cityid = '109223'
elif ecity.lower() == "tokyo":
cityid = '1850147'
elif ecity.lower() == "dubai":
cityid = '292224'
elif ecity.lower() == "new york":
cityid = '5128581'
elif ecity.lower() == "paris":
cityid = '6455259'
elif ecity.lower() == 'london':
cityid = '1006984'
elif ecity.lower() == "shanghai":
cityid = '1796236'
elif ecity.lower() == 'ottawa':
cityid = '6094817' #Ottawa city ID
apiurl = f'''http://api.openweathermap.org/data/2.5/weather?id={cityid}&appid={api}&units=metric'''
response = requests.get(apiurl)
if response.status_code == 200:
data = response.json()
cityname = data['name']
temperature = data['main']['temp']
condition = data['weather'][0]['description']
windspeed = data['wind']['speed']
alert = data.get('alerts')
print(f"Weather for {cityname}")
print("Temperature:", temperature)
print("Wind speed", windspeed)
print("Condition:", condition)
print(data)
msg_label.configure(text=f"Weather for {cityname}: ", font=('Arial', 20, 'bold'))
temp_label.configure(text=f"Temperature: {temperature}°C", font=('Arial', 20, 'bold'))
condition_label.configure(text=f"Condition: {condition}", font=('Arial', 20, 'bold'))
wind_label.configure(text=f"Wind speed: {windspeed}m/s", font=('Arial', 20, 'bold'))
alert_label.configure(text=f"Weather alerts: {alert}", font=('Arial', 20, 'bold'))
else:
print("Failed to fetch weather information.")
if 'rain' in condition.lower():
filename1 = 'rainy.jpeg'
elif 'light rain' in condition.lower():
filename1 = 'rainy.jpeg'
elif 'overcast clouds' in condition.lower():
filename1 = 'cloudy.jpg'
elif 'broken clouds' in condition.lower():
filename1 = 'cloudy.jpg'
elif 'sunny' in condition.lower():
filename1 = 'sunny.png'
elif 'sun' in condition.lower():
filename1 = 'sunny.png'
elif 'thunder storm' in condition.lower():
filename1 = 'thunderstorm.png'
elif 'snowy' in condition.lower():
filename1 = 'snowy.png'
elif 'snow' in condition.lower():
filename1 = 'snowy.png'
image_label = CTkLabel(app, image=c_img, text="")
image_label.pack()
name_entry.bind('<Return>', lambda event: update_weather(event))
update_weather(True)
msg_label.pack()
temp_label.pack()
condition_label.pack()
wind_label.pack()
alert_label.pack()
name_entry.pack()
app.mainloop()
I tried using a CTkLabel instead:
c_img = CTkImage(light_image=Image.open('cloudy.jpg'),size=(100, 100))
###Code###
c_img.configure(light_image = Image.open(filename1))
It updated, but only once, and printed out the image to the window.
You should create image_label
once instead of creating new one whenever update_weather()
is executed. And you need to update c_img
inside the function:
...
c_img = CTkImage(light_image=Image.open('cloudy.jpg'),size=(100, 100))
# create image_label here
image_label = CTkLabel(app, text="", image=c_img)
...
def update_weather(event):
...
# update image of c_img
c_img.configure(light_image=Image.open(filename1))
# don't create new label
#image_label = CTkLabel(app, image=c_img, text="")
#image_label.pack()
...
update_weather(True)
image_label.pack()
...