一、界面效果
二、完整代码
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