3

tkinter のかなり奇妙なバグに気付きました。少なくとも Win32 では、python が tcl と対話する方法に何かがあるためではないかと考えています。

ここに、gif 画像を表示する非常に単純なプログラムがあります。それは完全に機能します。

from Tkinter import *

canvas = Canvas(width=300, height=300, bg='white')   
canvas.pack()

photo=PhotoImage(file=sys.argv[1])
canvas.create_image(0, 0, image=photo, anchor=NW)  # embed a photo
print canvas
print photo

mainloop( )

ここで、プログラムを少し変更して、canvas オブジェクトを関数内から編集します。今回は、空白のキャンバスを取得します。

# demo all basic canvas interfaces
from Tkinter import *

canvas = Canvas(width=300, height=300, bg='white')

canvas.pack()

def set_canvas(cv):
    photo=PhotoImage(file=sys.argv[1])
    cv.create_image(0, 0, image=photo, anchor=NW)  # embed a photo
    print cv
    print photo

set_canvas(canvas)
mainloop( )

2 つの唯一の違いは、キャンバス オブジェクトが直接使用されるのではなく、関数に渡されることです。どちらの print ステートメントも同じ結果を返します。tcl/python レイヤーのオブジェクト モデルに何らかの故障があるのではないかと考えています。

皆さん、何か考えはありますか?

ありがとう、/YGA

4

1 に答える 1

6

簡単な解決策としてそれを行ってください、そして私は説明しようとします:

def set_canvas(cv):
    global photo # here!
    photo=PhotoImage(file=sys.argv[1])
    cv.create_image(0, 0, image=photo, anchor=NW)  # embed a photo
    print cv
    print photo

PhotoImageには、Pythonオブジェクトからの参照が少なくとも1つ必要です。そうでない場合、ガベージコレクションが行われます。私のソリューションではphoto、モジュールレベルの名前にすることをお勧めします。これにより、関数が終了しても、PhotoImageオブジェクトへの参照が残ります。クラスを作成set_canvasしてメソッドにし、PhotoImageオブジェクトをインスタンス変数として保存することをお勧めします。

于 2009-02-23T21:08:36.473 に答える