Tkinter气象应用报NameError:变量未定义,如何解决?
问题分析与解决方案
错误根源
- 变量作用域问题:
inside_temp_display等Label变量是在按钮点击函数内部定义的局部变量,clear_display函数无法访问这些局部变量,因此触发NameError。 - 控件重复创建:每次点击按钮都会新建一组Label,导致界面控件叠加,旧控件也无法被后续操作修改。
修复方案
- 在GUI初始化时提前创建所有需要的Label控件,设置初始文本为空,并将这些变量设为全局变量,确保所有函数都能访问。
- 按钮点击函数不再新建Label,而是直接更新已有Label的文本内容。
- 调整
clear_display函数,直接操作全局Label控件清空文本。
修改后的完整代码
from sense_emu import SenseHat from tkinter import * import requests import datetime as datetime sense = SenseHat() # ---- INSIDE TEMPERATURE, HUMIDTY AND PRESSURE ---- # inside_temp = round(sense.get_temperature(), 2) inside_humid = round(sense.get_humidity(), 2) inside_press = round(sense.get_pressure(), 2) # ---- OUTSIDE TEMPERATURE, HUMIDTY AND PRESSURE ---- # url = 'https://api.open-meteo.com/v1/forecast?latitude=45.8144&longitude=15.978&hourly=temperature_2m,relativehumidity_2m,surface_pressure&timezone=Europe%2FBerlin&forecast_days=1' response = requests.get(url) data = response.json() # ---- CALCULATE DIFFERENCES ---- # outside_temp_hourly = data['hourly']['temperature_2m'] outside_humid_hourly = data['hourly']['relativehumidity_2m'] outside_press_hourly = data['hourly']['surface_pressure'] temp_diff = [round(temp - inside_temp, 2) for temp in outside_temp_hourly] humid_diff = [round(hum - inside_humid, 2) for hum in outside_humid_hourly] press_diff = [round(press - inside_press, 2) for press in outside_press_hourly] # ---- GET CURRENT HOUR ---- # now = datetime.datetime.now() current_hour = now.hour # 全局声明显示用的Label变量 inside_temp_display = None outside_temp_display = None diff_temp_display = None inside_humid_display = None outside_humid_display = None diff_humid_display = None inside_press_display = None outside_press_display = None diff_press_display = None # ---- FUNCTIONS FOR THE BUTTONS ---- # def show_current_temp(): clear_display() inside_temp_display.config(text=f"Current inside temperature: {inside_temp}°C.") outside_temp_display.config(text=f"Current outside temperature: {outside_temp_hourly[current_hour]}°C.") diff_temp_display.config(text=f"Difference in temperature is: {abs(temp_diff[current_hour])}°C.") def show_current_humid(): clear_display() inside_humid_display.config(text=f"Current inside humidity: {inside_humid}%.") outside_humid_display.config(text=f"Current outside humidity: {outside_humid_hourly[current_hour]}%.") diff_humid_display.config(text=f"Difference in humidty is: {abs(humid_diff[current_hour])}%.") def show_current_press(): clear_display() inside_press_display.config(text=f"Current inside pressure: {inside_press}hPa.") outside_press_display.config(text=f"Current outside pressure: {outside_press_hourly[current_hour]}hPa.") diff_press_display.config(text=f"Difference in pressure is: {abs(press_diff[current_hour])}hPa.") def clear_display(): inside_temp_display.config(text="") outside_temp_display.config(text="") diff_temp_display.config(text="") inside_humid_display.config(text="") outside_humid_display.config(text="") diff_humid_display.config(text="") inside_press_display.config(text="") outside_press_display.config(text="") diff_press_display.config(text="") # ---- MAIN GUI PROGRAM ---- # def gui(): global inside_temp_display, outside_temp_display, diff_temp_display global inside_humid_display, outside_humid_display, diff_humid_display global inside_press_display, outside_press_display, diff_press_display root = Tk() root.title("Weather") root.geometry("700x600") title = Label(root, text="Weather info", font=("Arial", 20), pady=20) title.grid(row=0, column=1) temp_button = Button(root, text="Display temperature", command=show_current_temp) temp_button.grid(row=1, column=0, padx=40) humid_button = Button(root, text="Display humidity", command=show_current_humid) humid_button.grid(row=1, column=1, padx=45, pady=20) press_button = Button(root, text="Display pressure", command=show_current_press) press_button.grid(row=1, column=2, padx=40) # 初始化所有显示用的Label,设置为空文本 inside_temp_display = Label(root, pady=5) inside_temp_display.grid(row=2, column=1) outside_temp_display = Label(root, pady=5) outside_temp_display.grid(row=3, column=1) diff_temp_display = Label(root, pady=5) diff_temp_display.grid(row=4, column=1) inside_humid_display = Label(root, pady=5) inside_humid_display.grid(row=2, column=1) outside_humid_display = Label(root, pady=5) outside_humid_display.grid(row=3, column=1) diff_humid_display = Label(root, pady=5) diff_humid_display.grid(row=4, column=1) inside_press_display = Label(root, pady=5) inside_press_display.grid(row=2, column=1) outside_press_display = Label(root, pady=5) outside_press_display.grid(row=3, column=1) diff_press_display = Label(root, pady=5) diff_press_display.grid(row=4, column=1) root.mainloop() # 启动GUI gui()
注:已修复原代码中show_current_temp函数里误写的inside_temp_display.grid(row=4, column=1)错误,改为正确的diff_temp_display.grid(...)逻辑。
内容的提问来源于stack exchange,提问作者SolidOpt
相关产品推荐
相关产品推荐

