import tkinter as tk
from tkinter import ttk
import requests
import json
from datetime import datetime
from PIL import Image, ImageTk
import io
from ttkbootstrap import Style
class WeatherApp:
def __init__(self, root):
self.root = root
self.root.title("天气预报")
self.root.geometry("1000x800")
# 使用ttkbootstrap美化界面
style = Style(theme='cosmo')
# 创建主框架
self.main_frame = ttk.Frame(self.root)
self.main_frame.pack(pady=20, padx=20, fill='both', expand=True)
# 搜索框
self.search_frame = ttk.Frame(self.main_frame)
self.search_frame.pack(fill='x', pady=10)
self.city_entry = ttk.Entry(self.search_frame, font=('微软雅黑', 12))
self.city_entry.pack(side='left', expand=True, padx=(0, 10))
self.city_entry.insert(0, "上海")
self.search_button = ttk.Button(
self.search_frame,
text="查询",
command=self.get_weather,
style='primary.TButton'
)
self.search_button.pack(side='right')
# 当前天气信息框
self.current_weather_frame = ttk.LabelFrame(self.main_frame, text="当前天气", padding=15)
self.current_weather_frame.pack(fill='x', pady=10)
# 当前天气信息
self.current_info_frame = ttk.Frame(self.current_weather_frame)
self.current_info_frame.pack(fill='x', padx=20)
self.city_label = ttk.Label(self.current_info_frame, font=('微软雅黑', 20, 'bold'))
self.city_label.pack(anchor='w')
self.temp_label = ttk.Label(self.current_info_frame, font=('微软雅黑', 30))
self.temp_label.pack(anchor='w')
self.weather_label = ttk.Label(self.current_info_frame, font=('微软雅黑', 15))
self.weather_label.pack(anchor='w')
# 详细信息框
self.detail_frame = ttk.LabelFrame(self.main_frame, text="详细信息", padding=15)
self.detail_frame.pack(fill='x', pady=10)
# 创建详细信息标签
self.details = {
"体感温度": ttk.Label(self.detail_frame),
"湿度": ttk.Label(self.detail_frame),
"气压": ttk.Label(self.detail_frame),
"能见度": ttk.Label(self.detail_frame),
"风向": ttk.Label(self.detail_frame),
"风速": ttk.Label(self.detail_frame)
}
# 布局详细信息
row = 0
col = 0
for key, label in self.details.items():
ttk.Label(self.detail_frame, text=f"{key}:").grid(row=row, column=col * 2, padx=5, pady=5, sticky='e')
label.grid(row=row, column=col * 2 + 1, padx=5, pady=5, sticky='w')
col += 1
if col > 2:
col = 0
row += 1
# 未来天气预报框
self.forecast_frame = ttk.LabelFrame(self.main_frame, text="未来天气预报", padding=15)
self.forecast_frame.pack(fill='both', expand=True, pady=10)
# 创建未来5天的预报框架
self.forecast_days = []
for i in range(5):
day_frame = ttk.Frame(self.forecast_frame)
day_frame.pack(side='left', expand=True, padx=10)
date_label = ttk.Label(day_frame, font=('微软雅黑', 10))
date_label.pack()
temp_label = ttk.Label(day_frame, font=('微软雅黑', 12))
temp_label.pack()
weather_label = ttk.Label(day_frame, font=('微软雅黑', 10))
weather_label.pack()
self.forecast_days.append({
'date': date_label,
'temp': temp_label,
'weather': weather_label
})
def get_weather(self):
city = self.city_entry.get()
api_key = "你的API密钥" # 替换为你的API密钥
# 获取城市ID
location_url = f"https://geoapi.qweather.com/v2/city/lookup?location={city}&key={api_key}"
try:
# 获取城市ID
location_response = requests.get(location_url)
location_data = json.loads(location_response.text)
if location_data['code'] == '200' and location_data['location']:
city_id = location_data['location'][0]['id']
# 获取实时天气
current_url = f"https://devapi.qweather.com/v7/weather/now?location={city_id}&key={api_key}"
# 获取天气预报
forecast_url = f"https://devapi.qweather.com/v7/weather/7d?location={city_id}&key={api_key}"
# 获取当前天气
response = requests.get(current_url)
current_data = json.loads(response.text)
if current_data['code'] == '200':
now = current_data['now']
# 更新当前天气信息
self.city_label.config(text=f"{city}")
self.temp_label.config(text=f"{now['temp']}°C")
self.weather_label.config(text=f"{now['text']}")
# 更新详细信息
self.details["体感温度"].config(text=f"{now['feelsLike']}°C")
self.details["湿度"].config(text=f"{now['humidity']}%")
self.details["气压"].config(text=f"{now['pressure']}hPa")
self.details["能见度"].config(text=f"{now['vis']}km")
self.details["风向"].config(text=now['windDir'])
self.details["风速"].config(text=f"{now['windSpeed']}km/h")
# 获取天气预报
forecast_response = requests.get(forecast_url)
forecast_data = json.loads(forecast_response.text)
if forecast_data['code'] == '200':
daily_forecast = forecast_data['daily']
for i, day in enumerate(daily_forecast[:5]):
date = datetime.strptime(day['fxDate'], '%Y-%m-%d').strftime('%m/%d')
self.forecast_days[i]['date'].config(text=date)
self.forecast_days[i]['temp'].config(
text=f"{day['tempMin']}°C - {day['tempMax']}°C"
)
self.forecast_days[i]['weather'].config(text=day['textDay'])
else:
self.city_label.config(text="获取天气信息失败")
else:
self.city_label.config(text="未找到该城市")
except Exception as e:
print(f"错误信息: {str(e)}")
self.city_label.config(text="获取天气信息失败")
if __name__ == "__main__":
root = tk.Tk()
app = WeatherApp(root)
root.mainloop()
需要将代码中的api_key替换成你自己的,提前在和风天气官网注册一个账号并申请apikey
登录 | 和风天气