Jan-16-2022, 02:14 AM
I was intrigued by this post and thought I would make a tkinter weather app.
#! /usr/bin/env python3 # Do the imports import tkinter as tk import tkinter.font as tkfont from bs4 import BeautifulSoup as bs import requests import urllib import base64 # Create weather class to get info class Weather: def __init__(self): # Set some vars LANGUAGE = 'en-US, en;q=0.5' USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36" # session vars session = requests.Session() session.headers['User-Agent'] = USER_AGENT session.headers['Accept-Language'] = LANGUAGE session.headers['Content-Language'] = LANGUAGE # Url to google weather, get the data, use soup to parse url = 'https://www.google.com/search?lr=lang_en&ie=UTF-8&q=weather' data = session.get(url) soup = bs(data.text, 'html.parser') # Set an empty dict and grab the data we want self.results = {} self.results['region'] = soup.find('div', attrs={'id': 'wob_loc'}).text self.results['current temperature'] = soup.find('span', attrs={'id': 'wob_tm'}).text self.results['day and hour'] = soup.find('div', attrs={'id': 'wob_dts'}).text self.results['current weather'] = soup.find('span', attrs={'id': 'wob_dc'}).text self.results['precipitation'] = soup.find('span', attrs={'id': 'wob_pp'}).text self.results['humidity'] = soup.find('span', attrs={'id': 'wob_hm'}).text self.results['wind speed'] = soup.find('span', attrs={'id': 'wob_ws'}).text self.results['img'] = soup.find('img', attrs={'class': 'wob_tci', 'id': 'wob_tci'})['src'] # Create the tkinter window class class Window: def __init__(self, parent): # set the window parent and configure rows and columns self.parent = parent self.parent.columnconfigure(0, weight=1) self.parent.rowconfigure(0, weight=1) # Initiate the weather class self.weather = Weather() # Create the main container container = tk.Frame(self.parent) container.grid(column=0, row=0, sticky='news') container.grid_columnconfigure(0, weight=3) # Container to hold the data in our header header_container = tk.Frame(container) header_container.grid(column=0, row=0, sticky='new') header_container.grid_columnconfigure(1, weight=3) # Container for holding weather info self.info_container = tk.Frame(container) self.info_container.grid(column=0, row=1, sticky='news') for i in range(2): self.info_container.grid_columnconfigure(i, weight=3, uniform='info') # Label for the image self.img_label = tk.Label(header_container) self.img_label['image'] = self.get_image() self.img_label['relief'] = 'groove' self.img_label.grid(column=0, row=0, sticky='new') # Label for header text header = tk.Label(header_container) header['text'] = self.weather.results['region'] header['font'] = tkfont.Font(size=18, weight='bold') header['relief'] = 'groove' header['padx'] = 8 header['fg'] = 'blue' header.grid(column=1, row=0, sticky='news') # Create empty list for labels and set a counter self.labels = [] i = 0 # Loop through the dict and assign to labels for key, value in self.weather.results.items(): if key != 'region' and key != 'img': if key == 'current temperature': text = value.title() + '\u00b0' + ' F' else: text = value.title() self.labels.append([tk.Label(self.info_container, text=key.title(), anchor='w'), tk.Label(self.info_container, text=text, anchor='w')]) self.labels[i][0]['font'] = tkfont.Font(weight='bold', size=10) self.labels[i][0]['relief'] = 'groove' self.labels[i][1]['relief'] = 'groove' self.labels[i][0].grid(column=0, row=i, sticky='new', ipadx=5) self.labels[i][1].grid(column=1, row=i, sticky='new', ipadx=5) i += 1 # Call self.update to update the information self.update() # function/method for getting and returning the image def get_image(self): url = 'https:' + self.weather.results['img'] img = urllib.request.urlopen(url) raw = img.read() img.close() image = tk.PhotoImage(data=raw) image.img = image return image # Create the update function/method def update(self): self.img_label['image'] = self.get_image() i = 0 for key, value in self.weather.results.items(): if key != 'region' and key != 'img': if key == 'current temperature': text = value.title() + '\u00b0' + ' F' else: text = value.title() self.labels[i-1][1]['text'] = text i += 1 self.info_container.after(5000, self.update) def main(): root = tk.Tk() root.title('Tkinter Weather App') root['padx'] = 5 root['pady'] = 4 root.resizable(False, False) Window(root) root.mainloop() main()