可视化的天气预报系统-修复版

 下面是完整代码,请笑纳!如果觉得该作品还行,请一键3连,谢谢!

from tkinter import *
import requests
import json
from tkinter import messagebox
import datetime
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings("ignore")

root = Tk()

def main():
    root.title('天气查询系统')
    root.configure(bg='DarkOrange')
    root.resizable(width=False, height=False)

    with open("1.gif", "rb") as file:
        image0 = PhotoImage(data=file.read())
    label = Label(root, text='天气查询系统', fg="brown", font=20, compound='center', image=image0)
    label.image = image0
    label.grid(row=0, column=0, columnspan=2, sticky=W + E + N + S)

    Label(root, text='请输入城市', bg='DarkOrange').grid(row=1, column=0)
    Label(root, text="17-软件技术3班-学号-54Allen", fg="green", bg="yellow").place(x=125, y=5, width=162, height=20)
    enter = Entry(root)
    enter.grid(row=1, column=1, padx=10, pady=10)
    enter.delete(0, END)
    enter.insert(0, '深圳')
    running = 1

    def getCityCode(city):
        try:
            # 去掉城市名称末尾的“市”字
            if city.endswith('市'):
                city = city[:-1]

            headers = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
            }
            url = 'https://j.i8tq.com/weather2020/search/city.js'
            r = requests.get(url, headers=headers, timeout=5)
            r.raise_for_status()
            r.encoding = 'utf-8'
            json_str = r.text.split('=', 1)[1].strip().rstrip(';')
            city_dict = json.loads(json_str)

            for province in city_dict.values():
                for city_info in province.values():
                    for district, info in city_info.items():
                        if district == city:
                            return info['AREAID']
            x
            messagebox.showerror("错误", f"未找到城市: {city}")
            return "000000000"
        except requests.RequestException as e:
            messagebox.showerror("错误", f"网络请求失败: {e}")
            return "000000000"
        except json.JSONDecodeError as e:
            messagebox.showerror("错误", f"数据解析失败: {e}")
            return "000000000"
        except Exception as e:
            messagebox.showerror("错误", f"未知错误: {e}")
            return "000000000"

    
    def get_weather_data():
        city = enter.get()
        code = getCityCode(city)
        if code == "000000000":
            return []
        url = 'http://t.weather.sojson.com/api/weather/city/' + code
        try:
            r = requests.get(url, timeout=5)
            r.raise_for_status()
            info = r.json()
            if info['status'] == 200:
                weather_data = []
                forecast_data = info['data']['forecast']
                for forecast in forecast_data:
                    weather = {}
                    weather['城市:'] = info['cityInfo']['parent'] + info['cityInfo']['city']
                    weather['时间:'] = forecast['ymd'] + ' ' + forecast['week']
                    weather['湿度:'] = info['data']['shidu']
                    weather['PM2.5:'] = info['data']['pm25']
                    weather['PM10:'] = info['data']['pm10']
                    weather['空气质量:'] = info['data']['quality']
                    weather['温度:'] = info['data']['wendu']
                    weather['感冒指数:'] = info['data']['ganmao']

                    weather['日期:'] = forecast['date']
                    weather['最高温度:'] = forecast['high']
                    weather['最低温度:'] = forecast['low']
                    weather['年月日:'] = forecast['ymd']
                    weather['星期:'] = forecast['week']
                    weather['日出时间:'] = forecast['sunrise']
                    weather['日落时间:'] = forecast['sunset']
                    weather['空气质量指数::'] = forecast['aqi']
                    weather['风向:'] = forecast['fx']
                    weather['风级:'] = forecast['fl']
                    weather['天气类型:'] = forecast['type']
                    weather['温馨提示:'] = forecast['notice']

                    weather_data.append(weather)

                return weather_data
            else:
                messagebox.showerror("错误", '[' + city + ']不存在!')
        except requests.Timeout:
            messagebox.showerror("错误", "服务器请求繁忙,请稍后再试!")
        except (requests.HTTPError, json.JSONDecodeError) as e:
            messagebox.showerror("错误", str(e))
        return []

    def update_current_time(label):
        current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        label.config(text=current_time)
        label.after(1000, update_current_time, label)

    def show_data(weather_data, city):
        if not weather_data:
            return
        root1 = Toplevel()
        root1.geometry('1120x500')
        root1.resizable(width=False, height=False)
        root1.title(city + '未来五天的天气预报')
        root1.configure(bg='DarkOrange')

        current_time_label = Label(root1, font=('Arial', 12), fg='blue')
        current_time_label.pack(pady=10)
        update_current_time(current_time_label)

        for weather in weather_data:
            LANGS = [
                (str(weather['城市:']), '城市'),
                (str(weather['时间:']), '时间'),
                (str(weather['湿度:']), '湿度'),
                (str(weather['PM2.5:']), 'PM2.5'),
                (str(weather['PM10:']), 'PM10'),
                (str(weather['空气质量:']), '空气质量'),
                (str(weather['温度:']+'℃'), '当前温度'),
                (str(weather['最高温度:']), '最高温度'),
                (str(weather['最低温度:']), '最低温度'),
                (str(weather['年月日:']), '年月日'),
                (weather['星期:'], '星期'),
                (str(weather['日出时间:']), '日出时间'),
                (str(weather['日落时间:']), '日落时间'),
                (str(weather['空气质量指数::']), '空气质量指数'),
                (weather['风向:'], '风向'),
                (str(weather['风级:']), '风级'),
                (weather['天气类型:'], '天气类型'),
                (weather['温馨提示:'], '温馨提示')
            ]

            group = LabelFrame(root1, text='天气状况', padx=0, pady=0, fg="blue", bg='DarkOrange')
            group.pack(padx=11, pady=0, side=LEFT)
            for lang, value in LANGS:
                c = Label(group, text=value + ': ' + lang, bg='DarkOrange', fg='white')
                c.pack(anchor=W)
            Label(root1, text='提醒:今日' + weather['感冒指数:'], fg='blue').place(x=30, y=10)

        dates = [weather['年月日:'] for weather in weather_data]
        high_temps = [int(weather['最高温度:'].split(' ')[1].split('℃')[0]) for weather in weather_data]
        low_temps = [int(weather['最低温度:'].split(' ')[1].split('℃')[0]) for weather in weather_data]

        plt.figure(figsize=(16, 4))
        plt.plot(dates, high_temps, marker='o', label='最高温度')
        plt.plot(dates, low_temps, marker='o', label='最低温度')
        plt.xlabel('日期')
        plt.ylabel('温度(℃)')
        plt.title('未来5天气温趋势图')
        plt.legend()
        plt.grid(True)
        plt.xticks(rotation=45, ha='right')
        plt.tight_layout()
        plt.rcParams['font.sans-serif'] = ['SimSun']
        plt.rcParams['axes.unicode_minus'] = False
        for date, high_temp, low_temp in zip(dates, high_temps, low_temps):
            plt.text(date, high_temp, str(high_temp) + "℃", ha='center', va='bottom')
            plt.text(date, low_temp, str(low_temp) + "℃", ha='center', va='top')

        plt.show()
        root1.mainloop()

    def button_click():
        city = enter.get()
        button1.config(state=DISABLED)
        weather_data = get_weather_data()
        show_data(weather_data, city)
        button1.config(state=NORMAL)

    def destroy_windows():
        root.destroy()
        plt.close()

    button1 = Button(root, text="确认", width=10, command=button_click, bg='LimeGreen')
    button1.grid(row=4, column=0, sticky=W, padx=50, pady=5)
    button2 = Button(root, text='退出', width=10, command=destroy_windows, bg='LimeGreen')
    button2.grid(row=4, column=1, sticky=E, padx=50, pady=5)
    if running == 1:
        root.mainloop()

if __name__ == '__main__':
    main()
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

54Allen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值