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

Python Tkinter开发天气应用时Canvas组件不显示且无报错问题咨询

问题原因分析

你代码中Canvas无法正常显示是以下多个问题共同导致的:

  • 城市名称获取时机错误:CITY = e.get()写在全局作用域,程序启动时就执行,此时输入框无内容,拿到空字符串会导致天气接口请求失败,后续结果页逻辑不会执行。需要将该行代码移到func函数内部,点击按钮时再获取输入值。
  • Canvas父组件绑定错误:创建结果页Canvas时传入的父组件是主窗口y,导致Canvas被渲染到首页而非新建的结果页Toplevel对象上,需要将父组件改为结果页对象x。
  • 图片对象被垃圾回收:Tkinter的PhotoImage对象如果是函数局部变量,函数执行完成后会被Python自动回收,导致Canvas上的图片无法渲染。需要手动给图片添加持久引用,比如将其绑定到Canvas实例上。
  • 接口URL拼接错误:URL中的q=+多了多余的加号,会导致请求的城市参数异常,接口返回非200状态码,后续代码不会执行。
  • 多余的主循环调用:给Toplevel结果页单独调用x.mainloop()属于重复创建主循环,会导致窗口逻辑异常,主窗口的mainloop已经可以处理所有窗口的事件,无需单独调用。
修正后的完整代码
# 导入依赖
import requests, json
from tkinter import *

y = Tk()
y.geometry("500x500")
cvwid2 = 700
cvhei2 = 700
canvasi = Canvas(y, width=cvwid2, height=cvhei2, bg='black')
canvasi.pack(expand=YES, fill=BOTH)

imagei = 'images/home.png'
gif12 = PhotoImage(file=imagei)
canvasi.create_image(0, 0, image=gif12, anchor=NW)

e = Entry(y, width=50)
e.place(x=50,y=250)

def func():
    # 点击按钮时再获取输入的城市名
    CITY = e.get()
    BASE_URL = "https://api.openweathermap.org/data/2.5/weather?"
    # 修正URL拼接错误
    URL = "https://api.openweathermap.org/data/2.5/weather?q=" + CITY + "&units=metric&APPID=0316f9e49bb4c3fe9c8ea0327ea5a71e"
    response = requests.get(URL)
    if response.status_code == 200:
        data = response.json()
        main = data['main']
        temperature = main['temp']
        humidity = main['humidity']
        pressure = main['pressure']
        report = data['weather']
        print(f"{CITY:-^30}")
        print(f"Temperature: {temperature}")
        print(f"Humidity: {humidity}")
        print(f"Pressure: {pressure}")
        print(f"Weather Report: {report[0]['description']}")

        rep = report[0]['main'].lower()
        if "clear" in rep:
            image = 'images/sunny.png'
        if "cloud" in rep:
            image = 'images/cloud.png'
        if "rain" in rep:
            image = 'images/rain.png'
        if "thunder" in rep:
            image = 'images/thunder.png'
        if "mist" in rep:
            image = 'images/mist.png'
        if "snow" in rep:
            image = 'images/snow.png'

        x = Toplevel()
        x.resizable(False, False)
        gif = PhotoImage(file=image)
        cvwid = 700
        cvhei = 700
        # 修正Canvas父组件为结果页x
        canvas = Canvas(x, width=cvwid, height=cvhei, bg='blue')
        canvas.pack(fill=BOTH)
        # 给图片添加持久引用避免被回收
        canvas.gif = gif
        img = canvas.create_image(0,0, image=gif, anchor=NW)

        temp = canvas.create_text(cvwid / 2, 350,fill="White",font="Helvetica 30", text=str(int(temperature)) + "°C")
        reportr = canvas.create_text(cvwid / 2, 400,fill="White",font="Helvetica 20", text=report[0]["main"])

b = Button(y, text="Choose Country", command=func)
b.place(x=50, y=300)
y.mainloop()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 05:18:01