2016-04-28 74 views
0

我是一个在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和帆布与函数loadImage分开)。看到在command=loadImage()中插入括号就会造成问题。

发源于我的头一个问题还有一点:就被保持到filename=ImageTk.PhotoImage(img)参考解决了第一个问题。在函数内部保留引用通常不会毫无意义,因为它本身就是一个局部变量?

+0

要添加一个参数到你的命令,请点击这里。 http://stackoverflow.com/questions/6920302/how-to-pass-arguments-to-a-button-command-in-tkinter – Lafexlos

+0

是的,虽然不是第一个解决方案。我不得不使用部分从functools库,它的工作是这样的:'filemenu.add_command(标签=“加载图像”命令=部分(的LoadImage,帆布,IMG))' – Aetos

回答

1

正如effbot的PhotoImage页说,你必须保持你的形象的参考,以确保它不是垃圾收集。

你必须保持图像对象的引用在你的Python程序, 无论是将其存储在一个全局变量,或将其连接到 另一个对象。

注:当光象对象由Python的垃圾收集(如 当你从存储在本地 可变图像的功能返回),如果它被一个 显示的图像,甚至被清除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() 
+0

谢谢你的回答,这是资料,但不幸的是它不会产生我想要的结果。现在图像从一开始就被加载,我想要的是当我点击“加载图像”按钮时加载图像。 – Aetos

+0

@Aetos你可以在'filemenu.add_command(...,command = loadImage)'行检查你的'loadImage'旁边是否存在pativehesis吗?通常情况下,该行应该看起来像这样。而不是'filemenu.add_command(...,command = loadImage())'。 – Lafexlos

+0

Spot on :)现在我要编辑线程以包含一些附加内容。 – Aetos