用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

登录 | 和风天气

相关推荐
刘马想放假1 小时前
CANviz 使用指南|Linux 安装、DBC 解码、实时曲线与 J1939 实战
linux·python·websocket
2601_967987372 小时前
python判断变量名不要调用任何函数实现
python·函数·语法·判断·变量名
卷无止境3 小时前
SALib敏感性分析的python库学习笔记
后端·python
duansamve4 小时前
Python3+Flask+PostgreSQL18+Vue3项目生产环境用docker如何部署?
python·docker·flask
特立独行的猫A4 小时前
少 3 个环节、少 1 次 ABI、少 3500 行代码:cj-tauri 与 Ionic/Capacitor 的鸿蒙桥接机制对比
java·后端·python
特立独行的猫A4 小时前
cj-tauri vs Rust/Tauri 同款播放器实测:编译 21 秒 vs 11 分钟,磁盘 12 MB vs 1.2 GB
java·后端·python
李纲明5 小时前
微信小程序 getSystemInfo 提示已废弃、屏幕高度算错胶囊还对不齐?getWindowInfo 和 getDeviceInfo 怎么接才稳
javascript·微信小程序·小程序·小程序开发·devdiy
duansamve5 小时前
详解Flask中Session和Cookie
python·flask
威哥爱编程6 小时前
模拟面试智能体开发实战 04:面试聊到哪算哪?用状态机把整场面试编排起来
python·agent·harmonyos
威哥爱编程6 小时前
模拟面试智能体开发实战 03:AI 面试官太客气?人设 Prompt 让它像个真考官
python·agent·harmonyos