You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Tkinter Label中完整显示OpenWeatherMap多日天气预报?

解决Tkinter Label无法显示多日天气预报的问题

我一眼就看出问题出在你的format_response函数里——你每次循环都直接把新的天气数据覆盖到final_str上,而不是把内容累加起来!

问题根源

在你的原代码中:

def format_response(weather):
    for i in range(10):
        # ... 生成当天天气的代码 ...
        final_str = 'Date: %s ...' %(...)  # 每次循环都覆盖final_str
    return(final_str)

循环执行10次,但每次都会把final_str重置为当天的天气内容,最后返回的只是第10次循环的结果,所以Label只能显示单日预报。而用print的话,每次循环都会打印一次,所以Python Shell能看到所有内容,但return只能返回最后一次的值。

修复方案

我们需要初始化一个空字符串,然后在每次循环中把当天的天气信息追加进去,这样最后返回的就是所有天数的完整内容:

def format_response(weather):
    final_str = ""  # 初始化空字符串
    for i in range(10):
        dt_txt = weather['list'][i]['dt']
        date = (datetime.fromtimestamp(dt_txt)).strftime('%d-%b-%Y %H:%M:%S')
        desc = weather['list'][i]['weather'][0]['description']
        temp_min = weather['list'][i]['main']['temp_min']
        temp_max = weather['list'][i]['main']['temp_max']
        # 生成当天的天气字符串,加上换行和分隔空行提升可读性
        day_weather = 'Date: %s \nConditions: %s \nMin.Temperature(Celsius): %s\nMax.Temperature(Celsius): %s\n\n' %(date, desc, temp_min, temp_max)
        final_str += day_weather  # 追加到总字符串里
    return final_str

完整修改后的代码

import tkinter as tk
from tkinter import font
from PIL import ImageTk, Image
import requests
from datetime import datetime

HEIGHT = 700
WIDTH = 700

def format_response(weather):
    final_str = ""
    for i in range(10):
        dt_txt = weather['list'][i]['dt']
        date = (datetime.fromtimestamp(dt_txt)).strftime('%d-%b-%Y %H:%M:%S')
        desc = weather['list'][i]['weather'][0]['description']
        temp_min = weather['list'][i]['main']['temp_min']
        temp_max = weather['list'][i]['main']['temp_max']
        day_weather = 'Date: %s \nConditions: %s \nMin.Temperature(Celsius): %s\nMax.Temperature(Celsius): %s\n\n' %(date, desc, temp_min, temp_max)
        final_str += day_weather
    return final_str

def get_weather(city):
    api_key = 'a4aa5e3d83ffefaba8c00284de6ef7c3'
    url = 'https://api.openweathermap.org/data/2.5/forecast'
    params = {'APPID': api_key, 'q': city, 'units': 'metric'}
    response = requests.get(url, params = params)
    weather = response.json()
    label['text'] = format_response(weather)

root = tk.Tk()

canvas = tk.Canvas(root, height = HEIGHT, width = WIDTH)
canvas.pack()

background_image = ImageTk.PhotoImage(Image.open("D:/Documents/Python/GUI/Weather App/beach.png"))
background_label = tk.Label(root, image = background_image)
background_label.place(relwidth = 1, relheight = 1)

frame = tk.Frame(root, bg = '#b1cfff', bd = 5)
frame.place(relx = 0.5, rely = 0.15, relwidth = 0.80, relheight = 0.05, anchor = 'n')

entry = tk.Entry(frame, bg='#fce300', font = 40)
entry.place(relx = 0.0, rely = 0, relwidth = 0.75, relheight = 1)

button = tk.Button(frame, text = "SEARCH", font = 40, bg = 'black', fg = 'yellow', command = lambda: get_weather(entry.get()))
button.place(relx = 0.758, rely = 0, relwidth = 0.24, relheight = 1)

lower_frame = tk.Frame(root, bg = '#b1cfff', bd = 5)
lower_frame.place(relx = 0.5, rely = 0.25, relwidth = 0.80, relheight = 0.6, anchor = 'n')

label = tk.Label(lower_frame, font = ('courier new',10), bg = '#fce300', anchor = 'nw', justify = 'left')
label.place(relwidth = 1, relheight = 1)

root.mainloop()

额外提示

如果想显示每日汇总(而不是每3小时一次的数据),你可以根据日期分组,只保留每天的第一条记录或计算每日的平均/最高最低温,但这属于额外功能,你可以根据需求调整。

内容的提问来源于stack exchange,提问作者Wazzup83

火山引擎 最新活动