-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathUI.py
More file actions
223 lines (195 loc) · 9.29 KB
/
Copy pathUI.py
File metadata and controls
223 lines (195 loc) · 9.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
import tkinter as tk
from PIL import Image, ImageTk
import time
import GeocodingAPI
import ForecastAPI
import Visualization
y_alignment = 60
wmo_codes = {
# Index : [Name, type]
0:['Clear sky', 'clear'],
1:['Mainly clear', 'clear'],
2:['Partly cloudy', 'cloudy'],
3:['Overcast', 'overcast'],
45:['Fog', 'fog'],
48:['Rime fog', 'rime_fog'],
51:['Light drizzle','drizzle'],
53:['Moderate drizzle', 'drizzle'],
55:['Dense drizzle', 'drizzle'],
56:['Light, freezing drizzle', 'freezing_drizzle'],
57:['Dense, freezing drizzle', 'freezing_drizzle'],
61:['Slight rain', 'rain'],
63:['Moderate rain', 'rain'],
65:['Heavy rain', 'rain'],
66:['Freezing light rain', 'freezing_rain'],
67:['Freezing heavy rain', 'freezing_rain'],
71:['Slight snow fall', 'snow'],
73:['Moderate snow fall', 'snow'],
75:['Heavy snow fall', 'snow'],
77:['Snow grains', 'snow'],
80:['Slight rain showers', 'rain'],
81:['Moderate rain showers', 'rain'],
82:['Violent rain showers', 'rain'],
85:['Slight snow showers', 'snow'],
86:['Heavy snow showers', 'snow'],
95:['Thunderstorm', 'thunder'],
96:['Slight hailstorm', 'hail'],
99:['Heavy hailstorm', 'hail']
}
# Create the main window
root = tk.Tk()
root.title("Weather Forecasting Application")
root.geometry("1920x1080")
root.attributes('-fullscreen', True)
# Load and resize the background image to fit the window
background_image = Image.open("images//bg.jpg") # Replace with your image path
background_image = background_image.resize((1920, 1080), Image.Resampling.LANCZOS)
background_photo = ImageTk.PhotoImage(background_image)
# Create a canvas for the background image
canvas = tk.Canvas(root, width=1920, height=1080, highlightthickness=0)
canvas.pack()
# Set the background image on the canvas
canvas.create_image(0, 0, anchor=tk.NW, image=background_photo)
def try_destroying(element):
try:
element.destroy()
except Exception:
pass
images = []
weather_data = None
def display_results(latitude, longitude):
global weather_data
global images
images.clear()
canvas.delete('info_text')
canvas.delete('existing')
data = ForecastAPI.get_forecast(latitude,longitude,'temperature_2m','weathercode,temperature_2m_max,temperature_2m_min,sunrise,sunset,precipitation_probability_max','auto')
weather_data = data
x0, y0 = 17, root.winfo_screenheight()/2 - 50
x1, y1 = 217, root.winfo_screenheight() - 37
padx = 17
days = ["SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY"]
current_day_index =days.index(str(time.strftime('%A')).upper())
canvas.create_text(root.winfo_screenwidth()//2, 330, text=f"{str(data['latitude'])[:5]}°N {str(data['longitude'])[:5]}°E, {data['elevation']}m above sea level",
font=('Dubai', '18', 'bold'), fill='grey20', tags='info_text')
canvas.create_text(root.winfo_screenwidth()//2, 355, text=f"Generated in {str(data['generationtime_ms'])[:5]}ms, time in {data['timezone_abbreviation']} [{data['timezone']}]",
font=('Dubai', '14'), fill='grey20', tags='info_text')
for i in range(1,8):
if current_day_index >= 7:
current_day_index = current_day_index - 7
canvas.create_rectangle(x0,y0,x1,y1,fill='white',outline='white', tags='existing')
canvas.create_rectangle(x0,y0,x1,y0+50, fill='pink', outline='pink', tags='existing')
canvas.create_rectangle(x1,y1,x0,y1-35, fill='skyblue', outline='skyblue', tags='existing')
canvas.create_text((x1+x0)/2, (root.winfo_screenheight()//2 - 45), text=days[current_day_index], anchor=tk.N, justify='center',
font=('Dubai', '20', 'bold'), fill='white', tags='existing')
if i == 1:
canvas.create_text((x1+x0)/2, (root.winfo_screenheight() - 50 - 20), text='TODAY', anchor=tk.N, justify='center',
font=('Dubai', '15', 'bold'), fill='white', tags='existing')
else:
date = data['daily']['time'][i-1]
canvas.create_text((x1+x0)/2, (root.winfo_screenheight() - 50 - 20), text=date, anchor=tk.N, justify='center',
font=('Dubai', '15', 'bold'), fill='white', tags='existing')
weathercode = data['daily']['weathercode'][i-1]
icon = Image.open(f"images\\icons\\{wmo_codes[weathercode][1]}.png")
icon = icon.resize((160,160), Image.Resampling.LANCZOS)
icon = ImageTk.PhotoImage(icon)
images.append(icon)
canvas.create_image(x0+20, y0+60, image=icon, anchor = tk.NW)
canvas.create_text((x1+x0)/2, y0+240, text=wmo_codes[weathercode][0], anchor=tk.N, justify='center',
font=('Dubai', '15'), fill='black', tags='existing')
canvas.create_text((x1+x0)/2 - 25, y0+280, text="""MAX TEMP:
MIN TEMP:
SUNRISE:
SUNSET:
CHANCE OF RAIN:""",
anchor=tk.N, justify='left', font=('Dubai', '11', 'bold'), fill='grey', tags='existing')
canvas.create_text((x1+x0)/2 + 65, y0+280,
text=f"""{data['daily']['temperature_2m_max'][i-1]}°C
{data['daily']['temperature_2m_min'][i-1]}°C
{data['daily']['sunrise'][i-1][-5:]}
{data['daily']['sunset'][i-1][-5:]}
{data['daily']['precipitation_probability_max'][i-1]}%""",
anchor=tk.N, justify='right', font=('Dubai', '11', 'bold'), fill='black', tags='existing')
graph_button = tk.Button(canvas, text="Display temperature graph", width=4, height=1, font=('Dubai', '14'), relief='flat', command=display_graph)
graph_button.place(x=(root.winfo_screenwidth() - 300)// 2, y= root.winfo_screenheight() - 30, width=300, height=23)
x0 = x0 + 200 + padx
x1 = x1 + 200 + padx
current_day_index = current_day_index+1
result_list = None
result_data = None
selected_index = None
city = ''
def callback(event):
global selected_index
global city
curtext = entry.get()
selection = event.widget.curselection()
if selection:
index = selection[0]
data = event.widget.get(index)
city = data
entry.delete(0, tk.END)
entry.insert(0, data)
selected_index = index
else:
entry.delete(0, tk.END)
entry.insert(0, curtext)
def search_results():
global result_list
global result_data
global selected_index
keywd = entry.get()
try:
canvas.delete('info_text')
result_list.destroy()
except Exception:
pass
if selected_index != None:
canvas.create_text(root.winfo_screenwidth()/2, root.winfo_screenheight()/2, anchor=tk.N, text="Please wait... fetching information!",
font=('Century Gothic', '20', 'bold'), fill='white', tags='info_text')
latitude = GeocodingAPI.get_latitude(selected_index)
longitude = GeocodingAPI.get_longitude(selected_index)
display_results(latitude, longitude)
selected_index = None
return None
result_data = GeocodingAPI.get_geo_data(keywd, 6)
list_items = GeocodingAPI.get_city_search_results()
var = tk.Variable(value=list_items)
result_list = tk.Listbox(canvas, listvariable=var, justify='center', font=('Century Gothic', '15'), selectbackground='#87ceeb', selectforeground='#000000', highlightthickness=0)
result_list.place(x=(root.winfo_screenwidth() - 600) // 2 - 30, y=360 - y_alignment, width=600, height=len(list_items*24))
result_list.bind("<<ListboxSelect>>", callback)
canvas.create_text((root.winfo_screenwidth())// 2 - 30, 365+len(list_items*24) - y_alignment, font=('Century Gothic', '15', 'bold'), text=f"Your query produced {len(list_items)} results!", anchor=tk.NE
,tags='info_text')
def display_graph():
Visualization.display_graph(weather_data, city)
# Function to clear the default text when clicked
def clear_default_text(event):
if entry.get() == "Enter a city name":
entry.delete(0, tk.END)
x_spacing = 70
y_spacing = 5
frame_width = root.winfo_screenwidth()
frame_height = root.winfo_screenheight()
canvas_width = 5 * (frame_width + x_spacing) + x_spacing
canvas_height = 2 * (frame_height + y_spacing) + y_spacing
canvas_x = (root.winfo_screenwidth() - canvas_width) // 2
canvas_y = (root.winfo_screenheight() - canvas_height) // 2
canvas.configure(width=canvas_width, height=canvas_height)
canvas.pack_propagate(0)
# Top image
top_image_width = 1000
top_image_height = 200
top_image_path = "images\\logo.png"
top_image = Image.open(top_image_path)
top_image = top_image.resize((1000, 200), Image.Resampling.LANCZOS)
top_image = ImageTk.PhotoImage(top_image)
canvas.create_image((root.winfo_screenwidth() - top_image_width) // 2, y_spacing+30, image=top_image, anchor=tk.NW)
entry = tk.Entry(canvas, width=40, font=('Century Gothic', 20), relief='flat', justify='center')
entry.insert(0, "Enter a city name")
entry.place(x=(root.winfo_screenwidth() - 600) // 2 - 30, y=300 - y_alignment, width=600, height=60)
search_button = tk.Button(canvas, text="🔎", width=4, height=1, font=('Century Gothic', 20), relief='flat', command=search_results)
search_button.place(x=(root.winfo_screenwidth() - 600) // 2 + 570, y=300 - y_alignment, width=60, height=60)
# Bind the click event to clear the default text
entry.bind("<Button-1>", clear_default_text)
# Start the tkinter main loop
root.mainloop()