当前位置: 首页 > news >正文

用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

登录 | 和风天气

 

 

相关文章:

  • C++学习——顺序表(四)
  • SpringMVC (一)基础
  • 日志系统项目——准备工作了解类的设计模式如单例模式、工厂模式、代理模式
  • 图片隐写wp
  • 【eNSP实战】交换机和路由器配置链路聚合
  • 【MySQL】数据类型
  • API调用comfyui工作流,做一个自己的app,chatgpt给我写的前端,一键创建自己的卡通形象,附源码
  • 利用axios库的爬虫程序如何使用HTTP
  • 【Go | 从0实现简单分布式缓存】-7:增加etcd和gRPC功能
  • Windows控制台函数:设置区域属性函数FillConsoleOutputAttribute()
  • 静态路由配置实验相关过程
  • SOAP和REST的区别
  • 全方位 JVM 调优参数详解
  • 【BUG分析】微服务无法读取Nacos中的共享配置
  • MySQL事务及索引复习笔记
  • 笔记本电脑开机自动启用自定义电源计划方法
  • 利用java实现数据分析
  • FX-std::vector
  • 共享内存(System V)——进程通信
  • 计算机:基于深度学习的Web应用安全漏洞检测与扫描
  • 音著协宣布胜诉,虎牙公司终审被判侵权
  • 网络直播间销售玩具盲盒被指侵权,法院以侵犯著作权罪追责
  • 1至4月国家铁路发送货物12.99亿吨,同比增长3.6%
  • 天问二号探测器顺利转入发射区
  • 《掩耳盗邻》:富人劫富,是犯罪,也是赎罪?
  • 芬兰直升机相撞坠毁事故中五名人员全部遇难