This version should work world wide. May have some bugs when it comes to the wind direction arrow. I've tried testing it and the rain.
To try it create a virtual environment and use pip to run the requirements.txt to install needed modules.
You can download the zip file from http://my-python.org to get the images or create your own.
data.py
To try it create a virtual environment and use pip to run the requirements.txt to install needed modules.
You can download the zip file from http://my-python.org to get the images or create your own.
data.py
import openmeteo_requests import requests_cache from retry_requests import retry from datetime import datetime import json import requests class Data: ''' Class makes the calls for data and does some formatting ''' def __init__(self): # Setup the Open-Meteo API client with cache and retry on error cache_session = requests_cache.CachedSession('.cache', expire_after = 3600) retry_session = retry(cache_session, retries = 5, backoff_factor = 0.2) openmeteo = openmeteo_requests.Client(session = retry_session) location = json.loads(requests.get('http://ipinfo.io/json').text) info = { 'country': location.get('country'), 'region': location.get('region'), 'city': location.get('city'), 'latitude': location.get('loc').split(',')[0], 'longitude': location.get('loc').split(',')[1] } # Make sure all required weather variables are listed here # The order of variables in hourly or daily is important to assign them correctly below url = "https://api.open-meteo.com/v1/forecast" params = { "latitude": info['latitude'], "longitude": info['longitude'], "current": ["temperature_2m", "relative_humidity_2m", "apparent_temperature", "precipitation", "cloud_cover", "wind_speed_10m", "wind_direction_10m", "wind_gusts_10m"], "temperature_unit": "fahrenheit", "wind_speed_unit": "mph", "precipitation_unit": "inch", "timeformat": "unixtime" } responses = openmeteo.weather_api(url, params=params) response = responses[0] current = response.Current() # Create dict and set wind directions winddirect = {} winddirect['N'] = [0,360] winddirect['NNE'] = [n for n in range(1,45)] winddirect['NE'] = [45] winddirect['ENE'] = [n for n in range(46,90)] winddirect['E'] = [90] winddirect['ESE'] = [n for n in range(91,135)] winddirect['SE'] = [135] winddirect['SSE'] = [n for n in range(136,180)] winddirect['S'] = [180] winddirect['SSW'] = [n for n in range(181,225)] winddirect['SW'] = [225] winddirect['WSW'] = [n for n in range(226,270)] winddirect['W'] = [270] winddirect['WNW'] = [n for n in range(271,315)] winddirect['NW'] = [315] winddirect['NNW'] = [n for n in range(316,360)] # Some variables for testing conditions self.direct = round(current.Variables(6).Value()) precip = round(current.Variables(3).Value()) cloudy = round(current.Variables(4).Value()) # This loop sets text for wind direction for key, value in winddirect.items(): if round(current.Variables(6).Value()) in value: direct = key # Dict for holding cloudy conditions cloud = {} cloud['clear skies'] = [n for n in range(0,5)] cloud['partly cloudy'] = [n for n in range(5,51)] cloud['mostly cloudy'] = [n for n in range(51, 86)] cloud['cloudy'] = [n for n in range(86,101)] # Compairing cloud dict with retreived data for key, value in cloud.items(): if cloudy in value: option = key # Create dict for testing on image to show faze = {} faze['day'] = { 'clear skies':'sunny.png', 'partly cloudy':'day_cloudy.png', 'mostly cloudy': 'day_cloudy.png', 'cloudy': 'cloudy.png', 'rain': 'rain.png' } faze['night'] = { 'clear skies': 'moonlight.png', 'partly cloudy':'night_cloudy.png', 'mostly cloudy': 'night_cloudy.png', 'cloudy': 'cloudy.png', 'rain':'rain.png' } # Get the hour for testing if it's day or night # Broke it down to 12 hour periods 1am 6pm is day hour = datetime.now().strftime('%H') if hour >= '01' and hour <= '18': for key, value in faze['day'].items(): if key == option: img = faze['day'][key] if precip > 0: option = ' rain' img = faze['day']['rain'] else: for key, value in faze['night'].items(): if key == option: img = faze['night'][option] if precip > 0: img = faze['night']['rain'] option = ' rain' # Create dict and set key value pairs self.weather = {} self.weather['location'] = ', '.join([info['country'], info['city'], info['region']]) self.weather['Date'] = datetime.now().strftime('%A %B %d, %Y') self.weather['Time'] = datetime.now().strftime('%I:%M:%S %p') self.weather['temp'] = f'{round(current.Variables(0).Value())}°F' self.weather['humidity'] = f'{round(current.Variables(1).Value())}%' self.weather['feels like'] = f'{round(current.Variables(2).Value())}°F' self.weather['precipitation'] = f'{round(current.Variables(3).Value())}%' self.weather['cloud cover'] = f'{round(current.Variables(4).Value())}%' self.weather['wind speed'] = f'{round(current.Variables(5).Value())} mph' self.weather['wind direction'] = direct self.weather['wind gust'] = f'{round(current.Variables(7).Value())} mph' self.weather['image'] = (option, img)weather.py
from PySide6.QtWidgets import (QApplication, QMainWindow, QWidget, QGridLayout, QHBoxLayout, QVBoxLayout,QLabel, QFrame, QGraphicsScene, QGraphicsView) from PySide6.QtCore import Qt, QTimer from PySide6.QtGui import QPixmap, QImage, QIcon, QTransform from datetime import datetime from data import Data class Arrow: ''' Class creates the wind direction arrow ''' def __init__(self): ''' Set up Graphics screen and view ''' pixmap = QPixmap('images/arrow.png') self.pixmap = pixmap.scaled(pixmap.width()/1.25, pixmap.height()/1.25) self.scene = QGraphicsScene() self.view = QGraphicsView(self.scene) self.view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.view.setFrameStyle(0) self.view.setFixedHeight(20) self.view.setStyleSheet('padding-right: 50px; margin-left:-20px; margin-top:5px;') def viewarrow(self, direction=0, text=''): self.item = self.scene.addPixmap(self.pixmap) # Rotates the arrow self.item.setRotation(direction) self.item.setTransformOriginPoint( self.item.boundingRect().center()) self.item.setTransformationMode(Qt.SmoothTransformation) return self.view class Window(QMainWindow): def __init__(self): super().__init__() # image icon from https://www.flaticon.com pixmap = QPixmap('images/weather.png') appicon = QIcon(pixmap) self.setWindowIcon(appicon) self.setWindowTitle('Weather App') self.setFixedSize(400,450) # Create main container container = QVBoxLayout() widget = QWidget() widget.setLayout(container) self.setCentralWidget(widget) self.show() # Create the header header = QLabel('PySide6 Weather') header.setStyleSheet('background-color: #ffa500; color: #ffffff; font-size: 30px; \ font-weight: bold; font-family: cursive; padding: 10px;') header.setAlignment(Qt.AlignmentFlag.AlignCenter) # Add header to container container.addWidget(header) # Create content container self.content = QGridLayout() self.content.setSpacing(10) frame = QFrame() frame.setLayout(self.content) frame.setFrameStyle(QFrame.StyledPanel | QFrame.Plain) # Add content container to main container container.addWidget(frame) labels = ['location', 'date','time', 'temperature', 'humidity', 'feels like', 'precipitation', 'cloud cover', 'wind speed', 'wind direction', 'wind gust'] self.labels = [] for index, item in enumerate(labels): label = QLabel(f'{item.title()}:') label.setStyleSheet('font-weight:500; font-size: 16px;') self.content.addWidget(label, index,0,1,1) # self.content.addWidget(QLabel(), index, 1,1,1) for index, item in enumerate(labels): self.labels.append(QLabel()) self.labels[index].setStyleSheet('font-size: 16px;') self.content.addWidget(self.labels[index], index, 1,1,1, Qt.AlignmentFlag.AlignLeft) self.content.addWidget(QLabel(), index, 2,1,1) # Setup an image label self.img_label = QLabel() self.img_label.setStyleSheet('padding-left: 80px;') self.content.addWidget(self.img_label, 3,1,9,1, Qt.AlignmentFlag.AlignTop) # Setup image text label self.img_text = QLabel() self.img_text.setStyleSheet('margin-left:40px;') self.content.addWidget(self.img_text, 8,1,1,1, Qt.AlignmentFlag.AlignCenter) # Create container for footer footerframe = QGridLayout() footerframe.setSpacing(0) # Add footer container to main container container.addLayout(footerframe) # Create the logo image img = QPixmap('images/my-python-logo.png') img = img.scaled(40,20) # Add image to label logo = QLabel() logo.setAlignment(Qt.AlignmentFlag.AlignCenter) logo.setStyleSheet('background-color: #ffa500;padding:5px; margin-left: -5.5em;') logo.setPixmap(img) # Create logo text label = QLabel('™ my-python©') label.setAlignment(Qt.AlignmentFlag.AlignCenter) label.setStyleSheet('padding:5px;margin-left: 3em; font-size: 18px;') # Add logo image and text to footer container footerframe.addWidget(logo, 0,1,1,1) footerframe.addWidget(label,0,1,1,1) class Controller: def __init__(self, window, arrow): self.window = window self.arrow = arrow self.update() # Create a timer to update contents self.timer = QTimer() self.timer.setInterval(300000) self.timer.timeout.connect(self.update) self.timer.start() self.clock_timer = QTimer() self.clock_timer.setInterval(1000) self.clock_timer.timeout.connect(self.clock) self.clock_timer.start() def clock(self): now = datetime.now().strftime('%I:%M:%S %p') self.window.labels[2].setText(now) def update(self): ''' Method for updating window ''' # Intialize Data class data = Data() # Set index variable index = 0 # Loop through the data dict and update label text for key, val in data.weather.items(): if key != 'image': self.window.labels[index].setText(str(val)) index += 1 if key == 'wind direction': text = val # Calls the Arror class and updates arror direction self.window.content.addWidget(self.arrow.viewarrow(direction=data.direct, \ text=text), 9, 1,1,2, Qt.AlignmentFlag.AlignCenter) # Sets the image label with correct image cloudy sunny, rain, etc pixmap = QPixmap(f'images/{data.weather['image'][1]}') pixmap = pixmap.scaled(120,120) self.window.img_label.setPixmap(pixmap) # Set the text under the image self.window.img_text.setText(data.weather['image'][0].title()) if __name__ == '__main__': app = QApplication([]) controller = Controller(Window(), Arrow()) app.exec()
I welcome all feedback.
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags
Download my project scripts
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags
Download my project scripts