How to update text Labels in tkinter?

Viewed 119

Every time I click the button to get the weather (I used Json to get info from a website), the previous text remains and new text is printed under it, but I want the old text to be updated. How can I do that? Please help.

from tkinter import *
import requests
import json

root = Tk()
root.title("Weather")
root.geometry("600x400")

def RealWeather():

    try:
        api_request = requests.get("http://api.openweathermap.org/data/2.5/weather?appid=c2fc19de6fcd6869c4a9e167ee0f2eb7&q=" + city.get())
        api = json.loads(api_request.content)
        location = api['name'] + ", " + api['sys']['country']
        temp = int(api['main']['temp'] - 273.15)
        ws = api['wind']['speed']
        status = api['weather'][0]['main']

        Labelloc = Label(root, text="Location",background='#5182cf').grid(row=2,column=0)
        Label_loc = Label(root, text=location ,background='#5182cf').grid(row=2, column=1)

        Labeltemp = Label(root, text="Temperature",background='#5182cf').grid(row=3,column=0)
        Label_temp = Label(root, text=temp,background='#5182cf').grid(row=3,column=1)

        Labelws = Label(root, text="Wind Speed",background='#5182cf').grid(row=4,column=0)
        Label_ws = Label(root, text=ws,background='#5182cf').grid(row=4,column=1)

        Labelstatus = Label(root, text="Status",background='#5182cf').grid(row=5,column=0)
        Label_status = Label(root, text=status,background='#5182cf').grid(row=5,column=1)


    except Exception as e:
        api = "Error..."

    EmptyLabel = Label(root, text="", background='#5182cf').grid(row=1, column=0)


butn = Button(root, text="Search", command=RealWeather).grid(row=0, column=3)
Label1 = Label(root, text="Enter City: ").grid(row=0,column=0)
city = Entry(root)
city.grid(row=0, column=1, padx=20)

root.mainloop()
2 Answers

This is how I would proceed with your answer. First create the labels outside the function and use grid() on separate lines, so they are not None.

Labelloc = Label(root, text="Location",background='#5182cf')
Label_loc = Label(root)

Labeltemp = Label(root, text="Temperature",background='#5182cf')
Label_temp = Label(root)

Labelws = Label(root, text="Wind Speed",background='#5182cf')
Label_ws = Label(root)

Labelstatus = Label(root, text="Status",background='#5182cf')
Label_status = Label(root)

Now inside the function, you have to call the config() method to update the label each time the function is run:

Labelloc.grid(row=2,column=0) #grid it when the func is ran
Label_loc.config(text=location,background='#5182cf')
Label_loc.grid(row=2, column=1) #grid it when the func is ran

Labeltemp.grid(row=3,column=0) #grid it when the func is ran
Label_temp.config(background='#5182cf')
Label_temp.grid(row=3,column=1) #grid it when the func is ran

Labelws.grid(row=4,column=0) #grid it when the func is ran
Label_ws.config(text=ws,background='#5182cf')
Label_ws.grid(row=4,column=1) #grid it when the func is ran

Labelstatus.grid(row=5,column=0)
Label_status.config(text=status,background='#5182cf')
Label_status.grid(row=5,column=1)

So final code:

from tkinter import *
import requests
import json

root = Tk()
root.title("Weather")
root.geometry("600x400")

def RealWeather():

    try:
        api_request = requests.get("http://api.openweathermap.org/data/2.5/weather?appid=c2fc19de6fcd6869c4a9e167ee0f2eb7&q=" + city.get())
        api = json.loads(api_request.content)
        location = api['name'] + ", " + api['sys']['country']
        temp = int(api['main']['temp'] - 273.15)
        ws = api['wind']['speed']
        status = api['weather'][0]['main']

        Labelloc.grid(row=2,column=0)
        Label_loc.config(text=location,background='#5182cf')
        Label_loc.grid(row=2, column=1)

        Labeltemp.grid(row=3,column=0)
        Label_temp.config(background='#5182cf')
        Label_temp.grid(row=3,column=1)

        Labelws.grid(row=4,column=0)
        Label_ws.config(text=ws,background='#5182cf')
        Label_ws.grid(row=4,column=1)

        Labelstatus.grid(row=5,column=0)
        Label_status.config(text=status,background='#5182cf')
        Label_status.grid(row=5,column=1)

    except Exception as e:
        api = "Error..."

    EmptyLabel = Label(root, text="", background='#5182cf').grid(row=1, column=0)

butn = Button(root, text="Search", command=RealWeather).grid(row=0, column=3)
Label1 = Label(root, text="Enter City: ").grid(row=0,column=0)
city = Entry(root)
city.grid(row=0, column=1, padx=20)

Labelloc = Label(root, text="Location",background='#5182cf')
Label_loc = Label(root)

Labeltemp = Label(root, text="Temperature",background='#5182cf')
Label_temp = Label(root)

Labelws = Label(root, text="Wind Speed",background='#5182cf')
Label_ws = Label(root)

Labelstatus = Label(root, text="Status",background='#5182cf')
Label_status = Label(root)

root.mainloop()

If you wish to use threading then it would be like:

# all imports
import threading

.... #same all code 
butn = Button(root, text="Search", command=lambda: threading.Thread(target=RealWeather).start())
btn.grid(row=0, column=3)
.... #same all code

Why use threading? It wont freeze the GUI while python fetches data from api. Though using threading with tkinter is not a very good option, there are some downsides to it, but for this simple example, it might be fine to work with it.

Here's how to fix your problems by using the universal widget config() method I mentioned in my comment:

from tkinter import *
import requests
import json

root = Tk()
root.title("Weather")
root.geometry("600x400")


def create_labels():
    global Label_loc, Label_temp, Label_ws, Label_status

    Label(root, text="Location",background='#5182cf').grid(row=2,column=0)
    Label_loc = Label(root, background='#5182cf')
    Label_loc.grid(row=2, column=1)

    Label(root, text="Temperature",background='#5182cf').grid(row=3,column=0)
    Label_temp = Label(root, background='#5182cf')
    Label_temp.grid(row=3,column=1)

    Labelws = Label(root, text="Wind Speed", background='#5182cf').grid(row=4,column=0)
    Label_ws = Label(root, background='#5182cf')
    Label_ws.grid(row=4,column=1)

    Labelstatus = Label(root, text="Status", background='#5182cf').grid(row=5,column=0)
    Label_status = Label(root, background='#5182cf')
    Label_status.grid(row=5,column=1)


def RealWeather():
    # Not strickly necessary, but good documentation.
    global Label_loc, Label_temp, Label_ws, Label_status

    try:
        api_request = requests.get("http://api.openweathermap.org/data/2.5/weather?appid=c2fc19de6fcd6869c4a9e167ee0f2eb7&q=" + city.get())
        api = json.loads(api_request.content)
        location = api['name'] + ", " + api['sys']['country']
        temp = int(api['main']['temp'] - 273.15)
        ws = api['wind']['speed']
        status = api['weather'][0]['main']

        Label_loc.config(text=location)
        Label_temp.config(text=temp)
        Label_ws.config(text=ws)
        Label_status.config(text=status)

    except Exception as e:
        print('error occurred:', e)


create_labels()
butn = Button(root, text="Search", command=RealWeather)
butn.grid(row=0, column=3)
Label1 = Label(root, text="Enter City: ")
Label1.grid(row=0,column=0)
city = Entry(root)
city.grid(row=0, column=1, padx=20)

root.mainloop()

P.S. I also strongly suggest you read and start following the PEP 8 - Style Guide for Python Code.

Related