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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 11:39:18