Our Objective: To build a desktop-based Weather application using Python’s Tkinter Module and Weather API

Code a Weather App in Python using Tkinter
Code a Weather App in Python using Tkinter

Python is a high-level dynamic programming language. It has enormous applications in the field of booming technology like Machine Learning, Artificial Intelligence, Data Science, and many more. When you start exploring the world of python, you are tempted to try various python projects. The internet is filled with many such project ideas for you to try to better your skills.

This article also showcases one such python project that aims to cater the intermediate learners. In this project, we are going to code our own little desktop-based GUI application. We are going to use the only framework that’s built into the Python standard library, Tkinter. It helps you create basic-looking but powerful GUI applications with much ease and freedom. The major advantage of using Tkinter is its cross-platform compatibility.

Our Approach

We are going to build a Weather App in Python. Since it is a real-time weather application, we will be integrating API. We are going to use the Open Weather Map API to get the temperature and related information based on the location the user enters. Now let us briefly understand how we are going to program our idea:

  • We will firstly install and then import our required modules in the working file.
  • Then we will create a GUI application based on Tkinter.
  • After that, we will define our function to take the input and detect the location and assess the current time of the input location.
  • Now that we have the location, the function will move on to our main purpose, that is calling our weather API.
  • The API response will get us the temperature, wind, humidity and pressure record of the entered location.
  • And lastly, it will throw an error if the entered location is wrong or misspelled.

Make a Folder for Weather App

The very first step is to set up your system and files. Make a new folder in your working directory and open it within the code editor. Make a new file with the .py” extension. In this file, we’re going to write the script for this app.

Note: I have already downloaded and saved all the images required in this project in this folder only. You can get those images here. Make sure you save them within the same folder as your python file.

Importing the Required Modules

We will be using the following modules in this application:

  • tkinter: Amazing library to build Python GUI applications.
  • timezonefinder: It helps in locating the corresponding timezone for given coordinates on earth.
  • datetime: It is an inbuilt module that lets us manipulate dates and times and the format.
  • pillow: It is built over PIL, which is the largest image processing library used in python. Pillow will help us in resizing the logo image used in our application.
  • requests: It helps in sending HTTP requests to an API. It is one of the most downloaded python library.
  • geopy: It locates the coordinates of addresses, cities, countries, and landmarks across the globe using third-party geocoders and other data sources.
  • pytz: It is responsible for getting olson timezone database into python.
    • Olson is a format which uses known names of cities/regions.

So we need to install all of the above-mentioned modules in our system. Use the following code to install the modules if you don’t have them installed already.

pip install tkinter
pip install geopy
pip install timezonefinder
pip install pytz
pip install requests
pip install pillow 

Once you have successfully installed all the above modules, now let’s import them into our project file.

from tkinter import *
import tkinter as tk
from geopy.geocoders import Nominatim
from tkinter import ttk, messagebox
from timezonefinder import TimezoneFinder
from datetime import datetime
import requests
import pytz
from PIL import Image, ImageTk

Lets Create our Graphic User Interface

Now comes the interesting part. We will now create the UI for our desktop app using Tkinter. The process of creating a GUI application is a bit time taking and depends on individual preferences. This GUI code looks best on a “15.6” inches screen size, but if you find any displacement, then you just need to make some adjustments in the code to match your taste. However, the code to create the UI is mentioned below:

Note: Make sure to download the images and save them in the same folder to ensure a smooth run of the code, else you would need to give the path of your downloaded images correctly.

root = Tk()
root.title("Weather App")
root.geometry("900x600+300+200")
root.resizable(False, False)

# Search Box
Search_image = PhotoImage(file="search.png")
myimage = Label(image=Search_image)
myimage.place(x=220, y=20)

textfield = tk.Entry(
    root,
    justify="center",
    width=17,
    font=("Times New Roman", 24, "bold"),
    bg="#404040",
    fg="white",
    border=0,
)
textfield.place(x=240, y=40)
textfield.focus()

# Search Icon
Search_icon = PhotoImage(file="search_icon.png")
myimage_icon = Button(
    image=Search_icon, borderwidth=0, cursor="hand2", bg="#404040", command=getWeather
)
myimage_icon.place(x=600, y=32)

# Resizing the image
image = Image.open("logo.png")
# Resize the image using resize() method
resize_image = image.resize((250, 250))

# Logo
Logo_image = ImageTk.PhotoImage(resize_image)
logo = Label(image=Logo_image)
logo.size
logo.place(x=325, y=165)

# Bottom Box
Frame_image = PhotoImage(file="box.png")
frame_myimg = Label(image=Frame_image)
frame_myimg.place(x=10, y=450)
frame_myimg.pack(side=BOTTOM)

# Time
name = Label(root, font=("Arial", 16, "bold"))
name.place(x=380, y=100)
clock = Label(root, font=("Georgia", 20, "bold"))
clock.place(x=390, y=130)

# Labels
# Label 1
label1 = Label(
    root, text="WIND", font=("Georgia", 16, "bold"), fg="white", bg="#1ab5ef"
)
label1.place(x=180, y=510)
# Label 2
label1 = Label(
    root, text="HUMIDITY", font=("Georgia", 16, "bold"), fg="white", bg="#1ab5ef"
)
label1.place(x=370, y=510)
# Label 3
label1 = Label(
    root, text="PRESSURE", font=("Georgia", 16, "bold"), fg="white", bg="#1ab5ef"
)
label1.place(x=620, y=510)

# Temp and Condition
temp = Label(font=("Times New Roman", 40, "bold"), fg="#ee666d")
temp.place(x=420, y=410)
cond = Label(font=("Times New Roman", 16, "bold"))
cond.place(x=350, y=470)


# Fetched Values
wind = Label(text="....", font=("Times New Roman", 18, "bold"), bg="#1ab5ef")
wind.place(x=202, y=540)
humidity = Label(text="....", font=("Times New Roman", 18, "bold"), bg="#1ab5ef")
humidity.place(x=420, y=540)
pressure = Label(text="....", font=("Times New Roman", 18, "bold"), bg="#1ab5ef")
pressure.place(x=670, y=540)

root.mainloop()

We have made an object of the Tkinter class and given the title of our application. Then we have further made objects of Label, Button, and Entry classes. Following which we have defined properties like label text, grid, etc, to define the layout. On the search icon, we have embedded one command “getWeather”, which is an empty function as of now. On click, this function will only solve our purpose. Our GUI using the above code will look like this:

Weather App GUI using Tkinter
Weather App GUI using Tkinter

Now before defining our function that will do all the work, we need to have our API key ready.

Steps to Generate an API Key

We are going to use OpenWeatherMap API. So for that purpose, we need an API Key also. Follow the below-mentioned steps to generate your key.

  • Visit OpenWeatherMap‘s website.
    • Sign up for an account if you don’t have one. If you already have an account, login and directy use your API key.
  • Now from their menu, head over to the API section.
  • Click on API docunder “Current Weather Data“.
  • Since we are making a city based search, we need to integrate the first one, that has city name defined as one of its parameter.
Find your API key by clicking on it
Find your API key by clicking on it
  • Click on “{API key}” and it will direct you to your API key page.
  • It will look something like this. Save or copy this somewhere, as we are going to use this key to call our API.
The generated API Key will look something like this
The generated Key will look something like this

Writing the Function to Identify the Input Location and then to Call API

def getWeather():
    try:
        city = textfield.get()
        geolocator = Nominatim(user_agent="geoapiExercises")
        location = geolocator.geocode(city)
        obj = TimezoneFinder()
        result = obj.timezone_at(lng=location.longitude, lat=location.latitude)
        home = pytz.timezone(result)
        local_time = datetime.now(home)
        current_time = local_time.strftime("%I:%M %p")
        clock.config(text=current_time)
        name.config(text="CURRENT TIME")

        # Weather API
        api = (
            "https://api.openweathermap.org/data/2.5/weather?q="
            + city
            + "&appid=7563e0e9293af377**********"
        )

        json_data = requests.get(api).json()
        condition = json_data["weather"][0]["main"]
        description = json_data["weather"][0]["description"]
        tempt = int(json_data["main"]["temp"] - 273.15)
        feels_like = int(json_data["main"]["feels_like"] - 273.15)
        press = json_data["main"]["pressure"]
        humid = json_data["main"]["humidity"]
        wind_1 = json_data["wind"]["speed"]

        temp.config(text=(tempt, "°"))
        cond.config(text=(condition, "|", "FEELS", "LIKE", feels_like, "°"))
        wind.config(text=wind_1)
        humidity.config(text=humid)
        pressure.config(text=press)
    except Exception as e:
        messagebox.showerror("Weather App", "Invalid Input!")

The function getWeather() will get the location input from the text field. Then using the modules timezonefinder, pytz, and geopy, it will identify the location’s current time. Following which it will call the OpenWeatherMap’s API. Once it establishes the connection, the data will be retrieved in JSON format. We will fetch all the data from the API response that we require to display in our app. After that, we have just configured the labels with their fetched value.

Weather App in Python
Weather App in Python

You can always play around and retrieve the values that you need from the API. You can check an example of how this API response will look like, here. That’s it for this fun project, comment down below and share your opinion about this one. Please share this with the relevant audience as it keeps me motivated.

Here is the complete code of our Weather App:

from tkinter import *
import tkinter as tk
from geopy.geocoders import Nominatim
from tkinter import ttk, messagebox
from timezonefinder import TimezoneFinder
from datetime import datetime
import requests
import pytz
from PIL import Image, ImageTk

root = Tk()
root.title("Weather App")
root.geometry("900x600+300+200")
root.resizable(False, False)

def getWeather():
    try:
        city = textfield.get()
        geolocator = Nominatim(user_agent="geoapiExercises")
        location = geolocator.geocode(city)
        obj = TimezoneFinder()
        result = obj.timezone_at(lng=location.longitude, lat=location.latitude)
        home = pytz.timezone(result)
        local_time = datetime.now(home)
        current_time = local_time.strftime("%I:%M %p")
        clock.config(text=current_time)
        name.config(text="CURRENT TIME")
        # print(result)

        # Weather API
        api = (
            "https://api.openweathermap.org/data/2.5/weather?q="
            + city
            + "&appid=7563e0e9293af377**********"
        )

        json_data = requests.get(api).json()
        condition = json_data["weather"][0]["main"]
        description = json_data["weather"][0]["description"]
        tempt = int(json_data["main"]["temp"] - 273.15)
        feels_like = int(json_data["main"]["feels_like"] - 273.15)
        press = json_data["main"]["pressure"]
        humid = json_data["main"]["humidity"]
        wind_1 = json_data["wind"]["speed"]

        temp.config(text=(tempt, "°"))
        cond.config(text=(condition, "|", "FEELS", "LIKE", feels_like, "°"))
        wind.config(text=wind_1)
        humidity.config(text=humid)
        pressure.config(text=press)
    except Exception as e:
        messagebox.showerror("Weather App", "Invalid Input!")


# Search Box
Search_image = PhotoImage(file="search.png")
myimage = Label(image=Search_image)
myimage.place(x=220, y=20)

textfield = tk.Entry(
    root,
    justify="center",
    width=17,
    font=("Times New Roman", 24, "bold"),
    bg="#404040",
    fg="white",
    border=0,
)
textfield.place(x=240, y=40)
textfield.focus()

# Search Icon
Search_icon = PhotoImage(file="search_icon.png")
myimage_icon = Button(
    image=Search_icon, borderwidth=0, cursor="hand2", bg="#404040", command=getWeather
)
myimage_icon.place(x=600, y=32)

# Resizing the image
image = Image.open("logo.png")
# Resize the image using resize() method
resize_image = image.resize((250, 250))

# Logo
Logo_image = ImageTk.PhotoImage(resize_image)
logo = Label(image=Logo_image)
logo.size
logo.place(x=325, y=165)

# Bottom Box
Frame_image = PhotoImage(file="box.png")
frame_myimg = Label(image=Frame_image)
frame_myimg.place(x=10, y=450)
frame_myimg.pack(side=BOTTOM)

# Time
name = Label(root, font=("arial", 16, "bold"))
name.place(x=380, y=100)
clock = Label(root, font=("Georgia", 20, "bold"))
clock.place(x=390, y=130)

# Labels
# Label 1
label1 = Label(
    root, text="WIND", font=("Georgia", 16, "bold"), fg="white", bg="#1ab5ef"
)
label1.place(x=180, y=510)
# Label 2
label1 = Label(
    root, text="HUMIDITY", font=("Georgia", 16, "bold"), fg="white", bg="#1ab5ef"
)
label1.place(x=370, y=510)
# Label 3
label1 = Label(
    root, text="PRESSURE", font=("Georgia", 16, "bold"), fg="white", bg="#1ab5ef"
)
label1.place(x=620, y=510)

# Temp and Condition
temp = Label(font=("Times New Roman", 40, "bold"), fg="#ee666d")
temp.place(x=420, y=410)
cond = Label(font=("Times New Roman", 16, "bold"))
cond.place(x=350, y=470)


# Fetched Values
wind = Label(text="....", font=("Times New Roman", 18, "bold"), bg="#1ab5ef")
wind.place(x=202, y=540)
humidity = Label(text="....", font=("Times New Roman", 18, "bold"), bg="#1ab5ef")
humidity.place(x=420, y=540)
pressure = Label(text="....", font=("Times New Roman", 18, "bold"), bg="#1ab5ef")
pressure.place(x=670, y=540)

root.mainloop()

I appreciate the fact that you have read the till here. If you encounter any problem in the execution of the code or just want to share your feedback, please do contact me by commenting right here.

If you like the content and want to explore more about such fun projects, I am leaving links to our python series. Make sure to have a look at them too:

Python 01: How To Easily Convert Text To Handwritten Notes using Pywhatkit?

How to Easily Automate WhatsApp Messages? Python Project 02

How to Code a Simple GUI Calculator in Python using Tkinter

Python Script to Easily Organize Files & Folders and Save Time


Vaishali Rastogi

Hey There! I am Vaishali Rastogi and I am a tech-researcher. I've been doing writing for a good 4-5 years, so here I am now. Working on my own website to make people digitally aware of the updates in technology.

0 Comments

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *