GPIO引脚输入控制图片切换异常:首次运行正常,后续切换失效
问题分析与修复
你的代码存在几个核心问题,导致切换GPIO引脚时图片无法更新:
- 主窗口与事件循环重复创建:
root=Tk()和root.mainloop()被放在while True循环里,mainloop()是阻塞的,第一次运行后程序就卡在第一个窗口,无法响应后续的GPIO状态变化。 - 无意义的重复资源加载:每次循环都重新加载图片,既浪费资源,也不符合GUI程序的运行逻辑。
- 未复用显示组件:每次GPIO状态变化都新建Label,没有复用已有组件来更新内容。
修复后的代码
from tkinter import * import RPi.GPIO as GPIO # GPIO初始化 GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) GPIO.setup(18, GPIO.IN) GPIO.setup(17, GPIO.IN) # 主窗口初始化 root = Tk() root.geometry('1600x900') # 提前加载图片并保持引用(避免tkinter垃圾回收导致图片消失) pix = PhotoImage(file='1.png') pic = PhotoImage(file='3.png') # 可选:添加默认图片(当两个引脚都为低时显示) default_pic = PhotoImage(file='default.png') # 创建用于显示图片的标签 image_label = Label(root, image=default_pic) image_label.grid() def update_image(): # 获取当前GPIO状态 input_state1 = GPIO.input(18) input_state2 = GPIO.input(17) # 根据状态更新图片 if input_state1: image_label.config(image=pix) elif input_state2: image_label.config(image=pic) else: image_label.config(image=default_pic) # 每隔100毫秒调用一次自身,实现循环检测 root.after(100, update_image) # 启动更新循环 update_image() root.mainloop() # 程序退出时清理GPIO GPIO.cleanup()
关键改进点
- 使用tkinter的
after()方法替代while True,既实现了循环检测GPIO状态,又不会阻塞GUI事件循环。 - 只创建一次主窗口和显示标签,通过修改标签的
image属性实现图片更新。 - 提前加载所有图片并保持引用,避免tkinter的垃圾回收机制导致图片无法显示。
- 添加了GPIO清理代码,程序退出时释放资源。
内容的提问来源于stack exchange,提问作者hope_99
相关产品推荐
相关产品推荐

