2016-04-28 11 views
0

私はpythonで始まり、tkinterです。私は通常、キャンバスに画像を表示するコードを書いています。ボタンとキャンバスを使ってPythonで画像を表示

メインフレーム(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() 

EDIT: 第二の問題は、私はキャンバスとメイン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(label ="イメージをロード "、command = partial(loadImage、canvas、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'の横に小文字があるか確認してください。通常、その行は次のようになります。 'filemenu.add_command(...、command = loadImage()) 'ではありません。 – Lafexlos

+0

Spot on :)私はいくつかの追加を組み込むようにスレッドを編集します。 – Aetos

関連する問題