为什么在函数中创建的 Tkinter 图像不会显示?

2024-11-15 08:36:00
admin
原创
14
摘要:问题描述:此代码有效:import tkinter root = tkinter.Tk() canvas = tkinter.Canvas(root) canvas.grid(row = 0, column = 0) photo = tkinter.PhotoImage(file = './test.gif...

问题描述:

此代码有效:

import tkinter

root = tkinter.Tk()
canvas = tkinter.Canvas(root)
canvas.grid(row = 0, column = 0)
photo = tkinter.PhotoImage(file = './test.gif')
canvas.create_image(0, 0, image=photo)
root.mainloop()

它向我展示了图像。

现在,此代码可以编译,但是它没有显示图像,我不知道为什么,因为它是相同的代码,在一个类中:

import tkinter

class Test:
    def __init__(self, master):
        canvas = tkinter.Canvas(master)
        canvas.grid(row = 0, column = 0)
        photo = tkinter.PhotoImage(file = './test.gif')
        canvas.create_image(0, 0, image=photo)

root = tkinter.Tk()
test = Test(root)
root.mainloop()

解决方案 1:

该变量photo是一个局部变量,在类实例化后会被垃圾收集。解决方案涉及保存对照片的引用,例如:

self.photo = tkinter.PhotoImage(...)

如果你用 Google 搜索“tkinter 图像不显示”,第一个结果是这样的:

为什么我的 Tkinter 图像没有出现?

解决方案 2:

from tkinter import *
from PIL import ImageTk, Image

root = Tk()

def open_img():
    global img
    path = r"C:.....\\\"
    img = ImageTk.PhotoImage(Image.open(path))
    panel = Label(root, image=img)
    panel.pack(side="bottom", fill="both")
but1 = Button(root, text="click to get the image", command=open_img)
but1.pack()
root.mainloop() 

只需将 global 添加到 img 定义即可

解决方案 3:

问题是 Python 通过一个称为垃圾收集的过程自动删除对变量的引用。 解决方案是保存引用或创建新引用。

方法如下:

  1. 用来self增加引用计数并保存引用。

import tkinter

class Test:
    def __init__(self, master):
        canvas = tkinter.Canvas(master)
        canvas.grid(row = 0, column = 0)
        self.photo = tkinter.PhotoImage(file = './test.gif') # Changes here
        canvas.create_image(0, 0, image=self.photo) # Changes here

root = tkinter.Tk()
test = Test(root)
root.mainloop()
  1. 将其保存到列表中以增加引用计数并保存引用。

import tkinter
l=[]
class Test:

    def __init__(self, master):
        canvas = tkinter.Canvas(master)
        canvas.grid(row = 0, column = 0)
        photo = tkinter.PhotoImage(file = './test.gif')
        l.append(photo)
        canvas.create_image(0, 0, image=photo)

root = tkinter.Tk()
test = Test(root)
root.mainloop()

使用方法 2 时,您可以像我一样创建全局列表,也可以在类中使用列表。 两种方法都可以。

一些有用的链接:

  • 关于垃圾回收 1

  • 关于垃圾收集 2(更有用

解决方案 4:

根据经验,每当您在缩进的代码块中创建图像时,都需要安全地引用该图像。这是因为python的自动垃圾收集,当它破坏/离开该框架/页面/缩进的代码块时,它会收集引用计数为0的所有内容。


处理此问题的规范方法将图像列表放在全局命名空间中的某个位置,然后将图像引用添加到该列表中。这很方便,但效率不高,应该用于小型应用程序。

import tkinter as tk

global_image_list = []
global_image_list.append(tk.PhotoImage(file = 'test.png'))

一种更有效的方法是将一个属性绑定到您的小部件或类self.image,以便为您保存该引用,正如 Bryan 在他的回答中提出的那样。无论您这样做还是之前widget.image已分配,都没有区别widget = tk.Widget(..。但是,如果您想在小部件被销毁并被垃圾回收时继续使用该图像,这也可能不是正确的方法。

import tkinter as tk

root = tk.Tk()
label = tk.Label(root, text='test')
label.image = tk.PhotoImage(file = 'test.png')
label.configure(image=label.image)

解决方案 5:

只需将其添加global photo为函数内的第一行。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用