用Python写一个天气预报小程序

一、界面效果

二、完整代码

复制代码
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

登录 | 和风天气

相关推荐
用户8356290780517 小时前
从手动编辑到代码生成:Python 助你高效创建 Word 文档
后端·python
c8i7 小时前
python中类的基本结构、特殊属性于MRO理解
python
liwulin05068 小时前
【ESP32-CAM】HELLO WORLD
python
2501_915918418 小时前
iOS 上架全流程指南 iOS 应用发布步骤、App Store 上架流程、uni-app 打包上传 ipa 与审核实战经验分享
android·ios·小程序·uni-app·cocoa·iphone·webview
Doris_20238 小时前
Python条件判断语句 if、elif 、else
前端·后端·python
Doris_20238 小时前
Python 模式匹配match case
前端·后端·python
这里有鱼汤9 小时前
Python量化实盘踩坑指南:分钟K线没处理好,小心直接亏钱!
后端·python·程序员
00后程序员张9 小时前
iOS App 混淆与加固对比 源码混淆与ipa文件混淆的区别、iOS代码保护与应用安全场景最佳实践
android·安全·ios·小程序·uni-app·iphone·webview
大模型真好玩9 小时前
深入浅出LangGraph AI Agent智能体开发教程(五)—LangGraph 数据分析助手智能体项目实战
人工智能·python·mcp
测试老哥9 小时前
Selenium 使用指南
自动化测试·软件测试·python·selenium·测试工具·职场和发展·测试用例