通过Button和Canvas

时间:2016-04-28 12:35:40

标签: python image canvas tkinter

我是python中的begginer,tkinter。我编写的代码通常应该在画布中显示图像。

主框架(gui)与菜单栏一起显示,然后当我点击加载图像时,gui窗口收缩(我猜是100x100)但是没有显示内容。

请您解释一下为什么会发生这种情况,以便了解错误发生的位置以及纠正方法?

# -*- coding:utf-8 -*-
# Imports
from tkinter import Tk, Menu, Canvas
from PIL import Image, ImageTk

# Function definitions
def deleteImage(canvas):
    canvas.delete("all")
    return

def loadImage(canvas, img):
    filename = ImageTk.PhotoImage(img)
    canvas.image = filename
    canvas.create_image(0,0,anchor='nw',image=filename)
    return

def quitProgram():
    gui.destroy()
# Main window
gui = Tk()

# Inside the main gui window
#Creating an object containing an image
# A canvas with borders that adapt to the image within it
img = Image.open("fleur.jpg")
canvas = Canvas(gui,height=img.size[0],width=img.size[0])
canvas.pack()

# Menu bar
menubar = Menu(gui)
# Adding a cascade to the menu bar:
filemenu = Menu(menubar, tearoff=0)
menubar.add_cascade(label="Files", menu=filemenu)
# Adding a load image button to the cascade menu "File"
filemenu.add_command(label="Load an image", command=loadImage)
# Adding a delete image button to the cascade menu "File"
filemenu.add_command(label="Delete image", command=deleteImage)
filemenu.add_separator()
filemenu.add_command(label="Quit", command=quitProgram)
menubar.add_separator()
menubar.add_cascade(label="?")

# Display the menu bar
gui.config(menu=menubar)
gui.mainloop()

编辑: 第二个问题是我想在主gui窗口中创建一个画布和图像,并将它们作为参数传递给菜单按钮(参见上面的代码,其中img和canvas是与函数loadImage分开创建的) 。看作在command=loadImage()中放置括号会自行创建一个问题。

另一个在我脑海中提出问题的观点:关于通过引用filename=ImageTk.PhotoImage(img)来解决的第一个问题。在函数内部保留一个引用通常是没有意义的,因为它仍然是一个局部变量吗?

1 个答案:

答案 0 :(得分:2)

正如在effbot的PhotoImage页面中所述,您必须保留图像的参考,以确保它不会被垃圾收集。

  

您必须在Python程序中保留对图像对象的引用,   通过将其存储在全局变量中,或通过将其附加到   另一个对象。

     

注意:当Python对垃圾收集PhotoImage对象时(例如   当您从在本地存储图像的函数返回时   变量),即使正在显示图像,图像也会被清除   Tkinter小部件。

     

为避免这种情况,程序必须对图像保留额外的引用   宾语。一种简单的方法是将图像分配给窗口小部件   属性,像这样:

您的loadImage()方法应如下所示。

def loadImage():
    img = Image.open("fleur.jpg")
    filename = ImageTk.PhotoImage(img)
    canvas = Canvas(gui,height=100,width=100)
    canvas.image = filename  # <--- keep reference of your image
    canvas.create_image(0,0,anchor='nw',image=filename)
    canvas.pack()