Build a desktop weather app with a graphical interface - enter any city and get real-time temperature, humidity, and weather conditions using a free API.
This app uses the OpenWeatherMap API to fetch real weather data. You need a free API key:
a1b2c3d4e5f6g7h8i9j0...Tkinter is already built into Python, but we need to install requests:
pip install requests
Create a new file called weather_app.py in a folder of your choice.
Copy this complete code into your weather_app.py file. Replace YOUR_API_KEY with your actual key from Step 1:
# Weather App with Tkinter GUI - NKDevSpace Tutorial
import tkinter as tk
import requests
# ── Replace with your OpenWeatherMap API key ──
API_KEY = "YOUR_API_KEY"
def get_weather():
"""Fetch weather data from the API and display it."""
city = city_entry.get().strip()
if city == "":
result_label.config(text="Please enter a city name.", fg="#ef4444")
return
url = f"https://api.openweathermap.org/data/2.5/weather?q={city}&appid={API_KEY}&units=metric"
try:
response = requests.get(url, timeout=5)
data = response.json()
if data["cod"] == 200:
# Extract the data we need from the JSON response
temp = data["main"]["temp"]
feels = data["main"]["feels_like"]
humidity = data["main"]["humidity"]
condition = data["weather"][0]["description"].title()
wind = data["wind"]["speed"]
country = data["sys"]["country"]
result = (
f"📍 {city.title()}, {country}\n\n"
f"🌡️ Temperature : {temp}°C (Feels like {feels}°C)\n"
f"💧 Humidity : {humidity}%\n"
f"☁️ Condition : {condition}\n"
f"💨 Wind Speed : {wind} m/s"
)
result_label.config(text=result, fg="#e2e8f0")
elif data["cod"] == "404":
result_label.config(text="City not found! Check the spelling.", fg="#ef4444")
else:
result_label.config(text=f"Error: {data.get('message', 'Unknown error')}", fg="#ef4444")
except requests.exceptions.ConnectionError:
result_label.config(text="No internet connection. Please check your network.", fg="#ef4444")
except requests.exceptions.Timeout:
result_label.config(text="Request timed out. Try again.", fg="#ef4444")
except Exception as e:
result_label.config(text=f"Something went wrong: {str(e)}", fg="#ef4444")
# ── Build the GUI window ──
root = tk.Tk()
root.title("Weather App - NKDevSpace")
root.geometry("420x380")
root.resizable(False, False)
root.configure(bg="#0d1117")
# Title label
title_label = tk.Label(
root,
text="🌤️ Weather App",
font=("Poppins", 18, "bold"),
bg="#0d1117",
fg="#4f8ef7"
)
title_label.pack(pady=(24, 6))
subtitle = tk.Label(
root,
text="Enter a city to get real-time weather",
font=("Poppins", 10),
bg="#0d1117",
fg="#8899b0"
)
subtitle.pack()
# City input field
city_entry = tk.Entry(
root,
font=("Poppins", 13),
width=24,
bg="#161b27",
fg="#e2e8f0",
insertbackground="white",
relief="flat",
bd=8
)
city_entry.pack(pady=16)
city_entry.focus() # Auto-focus the input field
# Search button
search_btn = tk.Button(
root,
text="Get Weather",
font=("Poppins", 11, "bold"),
bg="#2563eb",
fg="white",
activebackground="#1d4ed8",
activeforeground="white",
relief="flat",
padx=20,
pady=8,
cursor="hand2",
command=get_weather
)
search_btn.pack()
# Result display label
result_label = tk.Label(
root,
text="",
font=("Poppins", 11),
bg="#0d1117",
fg="#e2e8f0",
justify="left",
wraplength=380
)
result_label.pack(pady=20, padx=20)
# Allow pressing Enter to search
root.bind('', lambda event: get_weather())
# Start the GUI event loop
root.mainloop()
root = tk.Tk()requests.get(url, timeout=5)data["main"]["temp"]data["main"] gets the "main" section, then ["temp"] gets the temperature from inside it. units=metric in the URL ensures the temperature is in Celsius.result_label.config(text=result, fg="#e2e8f0")root.bind('<Return>', lambda event: get_weather())cd path\to\your\folder
python weather_app.py