用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

登录 | 和风天气

相关推荐
傻啦嘿哟5 小时前
某招聘平台爬虫:爬取招聘岗位数据,分析各城市薪资水平
开发语言·爬虫·python
2501_933670795 小时前
2026秋招量化分析岗技能栈:Python、SQL、统计建模、回测项目怎么准备
开发语言·python·sql
2601_962077605 小时前
python Dejavu库快速识别音频指纹实例探究
python·音乐识别·dejavu库·音频指纹识别·实例探究
科技苑6 小时前
如何用Python编程实现一个简单的Web爬虫?
人工智能·python
dayDayupbetter6 小时前
Visual C++ 2010安装与使用高手秘籍
python
隐擎fox6 小时前
深入理解网络传输层安全:TLS 指纹识别(JA3/JA4)原理与 Python 协议层检测实战
爬虫·python·网络协议·安全·网络安全·https
医疗信息化王工6 小时前
DataForge:基于 Python 的数据库批量导出 Excel 工具——从架构到部署的全流程实战
数据库·python·excel
小玮看世界8 小时前
[Python]从合并区间到传感器融合区:合并区间在传感器区域融合的实际落地
开发语言·python
Java陈序员8 小时前
轻量运维面板!一款现代化的服务器控制面板工具!
运维·服务器·python·react.js·github
2601_962097368 小时前
1. 使用 C 或 C++ 扩展 Python
python·api·c·引用计数·扩展模块