You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python+Tkinter开发天气查询界面遇KeyError: 'main'问题求助

KeyError: 'main' 错误分析与修复方案

问题重现

尝试用Python+Tkinter开发城市气温查询界面时,运行到temp_kelvin=weatherinfo['main']['temp']行出现KeyError: 'main'报错,原代码如下:

from tkinter import *
import requests

root=Tk() 

root.title("WEATHER API")
root.geometry("400x400")
city=StringVar()
def getweather():
      CITY=city.get()
      api_id="abb8cea2239face8fbb7401add34d73e"

      URL="https://api.openweathermap.org/data/2.5/weather?"+CITY+"appid="+api_id
      response=requests.get(URL)
      weatherinfo = response.json()
      if weatherinfo['cod']!='404':
         temp_kelvin=weatherinfo['main']['temp']
         temp_celsius=temp_kelvin-273
         temp_farhenheit=temp_celsius *(9/5) + 32
         Labelc=Label(temp_celsius)

         Labelf=Label(temp_farhenheit)
         Labelc.pack()
         Labelf.pack()
      else:
         error=Label(text="ERROR")
         error.pack()

city=Entry(root)
city.pack()
Mybutton=Button(root,text="CHECK STATS",command=getweather).pack()

root.mainloop()

错误原因

  1. API请求URL格式错误:
    OpenWeatherMap的API要求城市参数必须用q=指定,且参数之间需用&分隔。原URL拼接后变成https://api.openweathermap.org/data/2.5/weather?城市名appid=密钥,属于无效请求,返回的JSON数据中没有main字段,直接访问就会触发KeyError。

  2. 变量名冲突:
    先定义city=StringVar(),之后又重新赋值city=Entry(root),导致getweather函数中调用的city.get()实际是Entry组件的方法,虽能获取输入内容,但写法混淆,且未将输入框与StringVar绑定,不符合Tkinter规范。

  3. Label组件创建错误:
    创建Label必须指定父容器(如root),且text参数需传入字符串。原代码中Label(temp_celsius)把温度数值当作父组件,会导致组件创建失败,无法正常显示温度。

修复方案

步骤1:修正API请求URL

用f-string拼接正确格式的URL,添加q=参数和&分隔符:

URL = f"https://api.openweathermap.org/data/2.5/weather?q={CITY}&appid={api_id}"

步骤2:解决变量名冲突并绑定StringVar

将StringVar变量名改为city_var,并绑定到Entry组件:

city_var = StringVar()
# ...
city_entry = Entry(root, textvariable=city_var)
city_entry.pack()
# 在getweather函数中获取值:
CITY = city_var.get()

步骤3:修正Label组件创建

创建Label时指定父容器和格式化后的温度文本:

c_label = Label(root, text=f"摄氏温度: {temp_celsius:.2f}°C")
f_label = Label(root, text=f"华氏温度: {temp_farhenheit:.2f}°F")

步骤4:完善错误处理

添加空输入检查、HTTP请求异常捕获,同时处理API返回cod为整数的情况。

完整修复代码

from tkinter import *
import requests

root = Tk() 
root.title("WEATHER API")
root.geometry("400x400")

# 定义StringVar并绑定到输入框
city_var = StringVar()

def getweather():
    CITY = city_var.get()
    if not CITY:
        error = Label(root, text="请输入城市名")
        error.pack()
        return
    
    api_id = "abb8cea2239face8fbb7401add34d73e"
    # 修正URL格式
    URL = f"https://api.openweathermap.org/data/2.5/weather?q={CITY}&appid={api_id}"
    
    try:
        response = requests.get(URL)
        response.raise_for_status()  # 捕获HTTP请求错误
        weatherinfo = response.json()
        
        # API返回的cod可能是整数
        if weatherinfo.get('cod') != 404:
            # 先检查main字段是否存在
            if 'main' in weatherinfo:
                temp_kelvin = weatherinfo['main']['temp']
                temp_celsius = temp_kelvin - 273.15  # 更精确的转换
                temp_farhenheit = temp_celsius * (9/5) + 32
                
                # 正确创建Label组件
                temp_title = Label(root, text="当前温度:")
                temp_title.pack()
                c_label = Label(root, text=f"摄氏: {temp_celsius:.2f}°C")
                c_label.pack()
                f_label = Label(root, text=f"华氏: {temp_farhenheit:.2f}°F")
                f_label.pack()
            else:
                error = Label(root, text="无法获取温度数据")
                error.pack()
        else:
            error = Label(root, text="城市不存在,请检查输入")
            error.pack()
    except requests.exceptions.RequestException as e:
        error = Label(root, text=f"请求出错: {str(e)}")
        error.pack()

# 创建输入框并绑定StringVar
city_entry = Entry(root, textvariable=city_var)
city_entry.pack()

# 创建按钮
check_btn = Button(root, text="CHECK STATS", command=getweather)
check_btn.pack()

root.mainloop()

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 22:50:41