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

Tkinter显示图片后Root停止更新问题求助

问题原因及解决方案

核心问题点

  • 重复启动事件循环:在buttoncallback里调用了root.mainloop(),而main函数中已经启动了一次事件循环,重复调用会导致后续按钮点击事件无法被处理。
  • 重复创建Label组件:每次点击按钮都新建一个Label显示二维码,旧Label仍留在界面上,新Label叠加在上方,视觉上无法感知更新。
  • 图片对象被垃圾回收:ImageTk.PhotoImage创建的img对象没有持久引用,Python垃圾回收机制会销毁它,导致二维码无法正常显示。

修正后的代码

import tkinter as tk 
import qrcode 
from PIL import ImageTk, Image

root = tk.Tk() 
root.geometry('300x300')
root.resizable(False, False)
root.title('QR-Code Maker')

def create_qrcode(data: str):
    qrc = qrcode.make(data, box_size=10)
    return qrc

def buttoncallback(entry, panel):
    data_for_qrcode = entry.get()
    qrc = create_qrcode(data_for_qrcode)
    qrc.save('QRCODE.PNG')

    img = ImageTk.PhotoImage(Image.open('QRCODE.PNG'))
    # 保存图片引用,防止被垃圾回收
    panel.img = img
    # 更新已有Label的图片内容
    panel.config(image=img)

def main():
    entry = tk.Entry(root)
    entry.pack(anchor=tk.CENTER)

    # 提前创建用于显示二维码的Label,初始为空
    panel = tk.Label(root)
    panel.pack(side='bottom', fill='both', expand='yes')

    button = tk.Button(root, text='Genereer QR', command=lambda: buttoncallback(entry, panel))
    button.pack(anchor=tk.CENTER)
    
    root.mainloop()

if __name__ == '__main__':
    main()

关键修改说明

  • 提前在main函数中创建显示二维码的panel,每次点击按钮仅更新该Label的图片属性,而非新建组件。
  • 将panel作为参数传入回调函数,方便直接更新其内容。
  • 将img对象绑定到panel.img上,保留持久引用,避免被垃圾回收。
  • 移除回调函数中的root.mainloop(),确保事件循环仅启动一次,后续按钮点击能正常响应。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 04:12:50