用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

登录 | 和风天气

相关推荐
阿坨26 分钟前
firestart:一行命令启动你的日常应用和网页
python·pypi·cli·click
老歌老听老掉牙36 分钟前
麻花钻切屑形态演变的力学机制与临界条件分析
python·算法·钻头
happylifetree1 小时前
Python18(补充):练习
python
weixin_416667962 小时前
银河麒麟V10看门狗试验-1
网络·chrome·python
古城小栈2 小时前
Pydantic 从入门到实践全讲解
python
happylifetree2 小时前
Python18:核心语法-数据存储与运算-运算符-算术运算符
python
打工仔折腾 AI2 小时前
从Attention到BERT:双向预训练语言模型到底解决了什么问题
人工智能·后端·python·深度学习·语言模型·bert
imperialeast2 小时前
创建WAV文件 韩文、德文、俄文等unicode音乐标签
windows·小程序
迅猛龙办公室3 小时前
实现第一个python程序(HelloWorld)
开发语言·python
拉格朗日(Lagrange)3 小时前
【第2 章】WorkBuddy 从入门到高手
开发语言·python