2016-04-28 73 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