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
相关产品推荐
相关产品推荐

