24 Apr I have created a simple app that displays the current weather using an API. I need to now use Tkinter Notebook to create a Tab that says ‘Current’
I have created a simple app that displays the current weather using an API. I need to now use Tkinter Notebook to create a Tab that says 'Current' and display the current weather under that tab.
I tried creating the tab in the view.py file named current_frame but I am lost in getting the code I wrote into that frame. I need someone to get the 'Current' tab to display the portion shown in blue in the attached photo in the Current frame.
WeatherApp/controller/__init__.py
WeatherApp/controller/__pycache__/__init__.cpython-310.pyc
WeatherApp/controller/__pycache__/controller.cpython-310.pyc
WeatherApp/controller/__pycache__/datacontroller.cpython-310.pyc
WeatherApp/controller/datacontroller.py
from model.weather import Weather from view.view import View # Changes in GUI class DataController: def __init__(self) -> None: self.view = View(self) self.weather = Weather() self.updateGUI() def main(self): self.view.main() def updateGUI(self): self.view.varLocation.set(self.weather.getLocation()) self.view.varCondition.set(self.weather.getConditionText()) self.view.varWindSpeed.set(self.weather.getWindSpeedMPH()) self.view.varWindDirection.set(self.weather.getWindDirection()) # To display Celsius or Fahrenheit if self.view.varUnits.get() == 1: self.view.varTemp.set(self.weather.getCurrentTempF()) self.view.varFeelsLike.set(self.weather.getFeelsLikeF()) else: self.view.varTemp.set(self.weather.getCurrentTempC()) self.view.varFeelsLike.set(self.weather.getFeelsLikeC()) def handleButtonSearch(self): location = self.view.varSearch.get() if location != '': self.weather = Weather(location) self.updateGUI()
WeatherApp/main.py
from controller.datacontroller import DataController if __name__ == '__main__': DataController().main() # Makes controller object, calls main function
WeatherApp/model/__init__.py
WeatherApp/model/__pycache__/__init__.cpython-310.pyc
WeatherApp/model/__pycache__/mapbox.cpython-310.pyc
WeatherApp/model/__pycache__/weather.cpython-310.pyc
WeatherApp/model/weather.py
import requests api = '6dbf96c62daf4869844214624221104' # url = 'http://api.weatherapi.com/v1/forecast.json?key=6dbf96c62daf4869844214624221104&q=London&days=3&aqi=yes&alerts=yes' class Weather: def __init__(self, location:str='Washington, DC'): self.weatherData = {} self.fetch(location) #—– Information —– def getLocationData(self, name): data = self.weatherData['location'][name] return str(data) def getCity(self): return self.getLocationData('name') def getState(self): return self.getLocationData('region') def getCountry(self): return self.getLocationData('country') def getTimeZone(self): return self.getLocationData('tz_id') def getLocation(self): # The code below allows for entries outside of the US based on the API return. if 'America' in self.getTimeZone(): return f'{self.getCity()}, {self.getState()}' else: return f'{self.getCity()}, {self.getCountry()}' def getCurrentData(self, name): data = self.weatherData['current'][name] return data if name == 'condition' else str(data) # If name of data is 'condition' return data as dict. if not return data as a string def getCurrentTempF(self): return self.getCurrentData('temp_f') + 'u00B0F' def getCurrentTempC(self): return self.getCurrentData('temp_c') + 'u00B0C' def getConditionText(self): condition = self.getCurrentData('condition') return str(condition['text']) def getConditionIcon(self): pass def getWindSpeedMPH(self): return self.getCurrentData('wind_mph') + ' MPH' def getWindDirection(self): return self.getCurrentData('wind_dir') def getFeelsLikeF(self): return self.getCurrentData('feelslike_f') + 'u00B0F' def getFeelsLikeC(self): return self.getCurrentData('feelslike_c') + 'u00B0C' def fetch(self, location): try: url = f'http://api.weatherapi.com/v1/forecast.json?key={api}&q=' + f'{location}&days=3&aqi=yes&alerts=yes' self.weatherData = requests.get(url).json() except: self.weatherData = {'error'}
WeatherApp/view/__init__.py
WeatherApp/view/__pycache__/__init__.cpython-310.pyc
WeatherApp/view/__pycache__/view.cpython-310.pyc
WeatherApp/view/view.py
import tkinter from tkinter.constants import TOP, LEFT, RIGHT, BOTTOM, W, E # CLEANED UP IMPORTS 4/18/22 from tkinter import StringVar, IntVar from tkinter.ttk import Frame, Entry, Label, Button, Radiobutton, Notebook, Style # CLEANED UP IMPORTS 4/18/22, IMPORTED NOTEBOOK 4/19 # GUI class View(tkinter.Tk): def __init__(self, controller): super().__init__() # GUI Design self.geometry('400×350') self.title('Weather App v1') #—– Notebook —– added 4/19 notebook = Notebook(self) notebook.pack(pady=10, expand=True) self.configure(bg='RoyalBlue1') self.controller = controller self.bind('<Return>') # Allows user to press enter in lieu of clicking search button #—– Variables —– self.varSearch = StringVar() self.varTemp = StringVar() self.varLocation = StringVar() self.varCondition = StringVar() self.varFeelsLike = StringVar() self.varWindSpeed = StringVar() self.varWindDirection = StringVar() self.varUnits = IntVar() self.varDay = StringVar() self.varTemp.set("Hot") self.varLocation.set("Really Hot") #—– Frames —– self.mainframe = Frame(self) self.mainframe.pack(side=TOP) self._createFrameSearchBar() self._createFrameInfo() self._createFrameDetails() self._createFrameControl() #—– Ttk Style —– style = Style() style.theme_create('WeatherStyle', parent='alt', settings={'TNotebook': {'configure': {'tabmargins': [0, 0, 2, 2] } }, 'TNotebook.Tab': {'configure': {'padding': [10, 5], 'background': '#33FFC6' },}}) style.theme_use('WeatherStyle') # Current Tab current_frame = Frame(notebook, width=400, height=280) current_frame.pack(fill='both', expand=True) notebook.add(current_frame, text='CurrentnWeather') # GUI Search Bar to enter city name def _createFrameSearchBar(self): self.frameSearchBar = Frame(self.mainframe) # TextBox to enter city name searchBox = Entry(self.frameSearchBar, textvariable=self.varSearch, width=15, font=('Arial', 15)) searchBox.focus_get() # Search button buttonSearch = Button(self.frameSearchBar, text = 'Search', command=self.controller.handleButtonSearch, width=15) searchBox.pack(padx=15, side=LEFT) buttonSearch.pack(side=BOTTOM) self.frameSearchBar.pack() # Frame to show results of search def _createFrameInfo(self): self.frameInfo = Frame(self.mainframe) labelTemp = Label(self.frameInfo, font=('Arial', '25'), textvariable=self.varTemp) labelLocation = Label(self.frameInfo, textvariable=self.varLocation) labelIcon = Label(self.frameInfo, text='Image') labelTemp.pack(pady=5) labelLocation.pack(pady=5) labelIcon.pack(pady=5) self.frameInfo.pack() def _createFrameDetails(self): self.frameDetails = Frame(self.mainframe) labelConditionLeft = Label(self.frameDetails, text='Current Condition:') labelFeelsLikeLeft = Label(self.frameDetails, text='Feels Like:') labelWindSpeedLeft = Label(self.frameDetails, text='Wind Speed:') labelWindDirectionLeft = Label(self.frameDetails, text='Wind Direction:') labelConditionRight = Label(self.frameDetails, textvariable=self.varCondition) labelFeelsLikeRight = Label(self.frameDetails, textvariable=self.varFeelsLike) labelWindSpeedRight = Label(self.frameDetails, textvariable=self.varWindSpeed) labelWindDirectionRight = Label(self.frameDetails, textvariable=self.varWindDirection) labelConditionLeft.grid(row=0, column=0, pady=5, sticky=W) labelConditionRight.grid(row=0, column=1, pady=5, sticky=E) labelFeelsLikeLeft.grid(row=1, column=0, pady=5, sticky=W) labelFeelsLikeRight.grid(row=1, column=1, pady=5, sticky=E) labelWindSpeedLeft.grid(row=2, column=0, pady=5, sticky=W) labelWindSpeedRight.grid(row=2, column=1, pady=5, sticky=E) labelWindDirectionLeft.grid(row=3, column=0, pady=5, sticky=W) labelWindDirectionRight.grid(row=3, column=1, pady=5, sticky=E) self.frameDetails.pack() def _createFrameControl(self): self.frameControls = Frame(self.mainframe) # Radio buttons radioF = Radiobutton(self.frameControls, text='Fahrenheit', variable=self.varUnits, value=1, command=self.controller.updateGUI) radioC = Radiobutton(self.frameControls, text='Celsius', variable=self.varUnits, value=2, command=self.controller.updateGUI) radioF.invoke() radioF.pack(side=LEFT, padx=7.5, pady=5) radioC.pack(side=RIGHT, padx=7.5, pady=5) self.frameControls.pack() def main(self): self.mainloop()
