Python 在tkinter画布中显示图像
我在尝试创建画布图像时遇到了一些问题,一个类处理图像的创建,我希望该类创建的图像与我调用它的次数相同 我的密码是Python 在tkinter画布中显示图像,python,canvas,tkinter,Python,Canvas,Tkinter,我在尝试创建画布图像时遇到了一些问题,一个类处理图像的创建,我希望该类创建的图像与我调用它的次数相同 我的密码是 from tkinter import * from random import * canvas_width = 800 canvas_height = 800 master = Tk() canvas = Canvas(master, width=canvas_width, height=canvas_height, bg="black") canvas.pack() de
from tkinter import *
from random import *
canvas_width = 800
canvas_height = 800
master = Tk()
canvas = Canvas(master, width=canvas_width, height=canvas_height, bg="black")
canvas.pack()
def images():
for _ in range(3):
Image_creator().create_image()
class Image_creator:
def create_image(self):
start_x = randint(1, canvas_width//2)
start_y = randint(1, canvas_height//2)
img = PhotoImage(file="pac_inizio.png")
master.img = img
self.image = canvas.create_image(start_x, start_y, anchor=NW, image=img)
images()
mainloop()
实际上,这段代码只显示了3个图像中的1个,我认为其他2个画布图像是创建的,但里面没有图像。
我试图改变create按钮的create_image函数,而不是canvas image,并了解它是否真的如我所想。
如果你用修改过的函数运行代码,它会显示3个按钮,但只有一个按钮里面有图像
def create_image(self):
start_x = randint(1, canvas_width//2)
start_y = randint(1, canvas_height//2)
img = PhotoImage(file="pac_inizio.png")
master.img = img
self.image = Button( anchor=NW, image=img)
self.image.place(x=start_x, y=start_y)
我认为问题在于图像引用,但不知道如何解决它您似乎意识到
tkinter
中的图像被垃圾收集的常见问题,尽管它们仍在某处使用,除非有明确的图像引用。但是,请注意,如果使用master.img=img
,则始终只能引用三个(相同)图像中的一个。如果这些图像与您的实际代码不同,请创建一个列表(或使用全局分数中的任何其他列表来存储图像)
但是,由于图像是相同的,您也可以直接在全局范围内(而不是在方法中)加载图像一次,然后使用该图像。此外,仅为该方法使用该类也没有多大意义(因为实例也是在循环中进行垃圾收集的)
您似乎意识到了
tkinter
中的图像被垃圾收集的常见问题,尽管它们仍在某处使用,除非有对该图像的明确引用。但是,请注意,如果使用master.img=img
,则始终只能引用三个(相同)图像中的一个。如果这些图像与您的实际代码不同,请创建一个列表(或使用全局分数中的任何其他列表来存储图像)
但是,由于图像是相同的,您也可以直接在全局范围内(而不是在方法中)加载图像一次,然后使用该图像。此外,仅为该方法使用该类也没有多大意义(因为实例也是在循环中进行垃圾收集的)
我认为问题在于使用
master.img=img
时,您在任何时候都只持有对其中一个图像的引用;这些垃圾被收集起来。试着把master.img
做成一个列表或类似的东西。(另外,仅仅为create_image
方法创建一个类似乎是毫无意义的。)Read我认为问题在于,使用master.img=img
时,您在任何时候都只持有对其中一个图像的引用;这些垃圾被收集起来。试着把master.img
做成一个列表或类似的东西。(另外,仅仅为create_image
方法创建一个类似乎是毫无意义的。)阅读我认为这里的实际问题不是你在第一段中描述的。它们正确地保存了类中的所有三个图像,但没有保存Image\u creator
类的实例。既然该实例被垃圾回收,那么其中的图像也会被垃圾回收。@BryanOakley怎么会这样?请注意,OP会执行master.img=img
,而不是self.img=img
,以及self.image=canvas。create_image(…)
只会保护画布上图像对象的ID,而不会保护实际的PhotoImage
,对吗?哦,哇,我没听清楚master.img=…
不好。我注意到的部分是:Image\u creator().create\u Image()
-OP正在为每个图像创建一个Image\u creator
的新实例,但没有保存这些实例。我猜代码中有两个问题,而不是一个。@BryanOakley是的,我也试图指出这一点,但实际上我并不认为这是一个很大的问题。该实例似乎根本不需要,因此您可以将其设置为常规函数。但是指出这些事情当然是好的,因为它们可能暗示对事情如何运作或必须做的一些误解。我认为这里的实际问题不是你在第一段中描述的。它们正确地保存了类中的所有三个图像,但没有保存Image\u creator
类的实例。既然该实例被垃圾回收,那么其中的图像也会被垃圾回收。@BryanOakley怎么会这样?请注意,OP会执行master.img=img
,而不是self.img=img
,以及self.image=canvas。create_image(…)
只会保护画布上图像对象的ID,而不会保护实际的PhotoImage
,对吗?哦,哇,我没听清楚master.img=…
不好。我注意到的部分是:Image\u creator().create\u Image()
-OP正在为每个图像创建一个Image\u creator
的新实例,但没有保存这些实例。我猜代码中有两个问题,而不是一个。@BryanOakley是的,我也试图指出这一点,但实际上我并不认为这是一个很大的问题。该实例似乎根本不需要,因此您可以将其设置为常规函数。但是,指出这些事情当然是好的,因为它们可能会暗示人们对事情如何运作或必须做的一些误解。
img = PhotoImage(file="pac_inizio.gif") # create once in global score
def create_image(): # regular function, not method
start_x = randint(1, canvas_width//2)
start_y = randint(1, canvas_height//2)
canvas.create_image(start_x, start_y, anchor=NW, image=img)