0

メニューを介して他のフレームを開閉するメイン フレーム (ルート) を持つプログラムを開発しようとしています。メインフレームには問題なく挿入された画像がありますが、別のフレームを開いて新しい画像を挿入しようとするとすぐに:

    canvas = Canvas(date-time_window, width = 200, height = 200, bg = 'yellow') 
canvas.create_image(0, 0, image = moon_photo, anchor = NW)

pyimage2 doesn't exist というエラーが表示されますが、フレームへの参照を削除すると、次のようになります。

    canvas = Canvas(width = 200, height = 200, bg = 'yellow')

画像はルート フレームに表示されますが、もちろん、必要なフレームには表示されません。

一度に複数のフレームで画像を表示することはできますか?

また、メイン フレームを閉じて、完全に再起動せずに再度開くと、メイン フレームに表示されている画像で同じエラーが発生することにも気付きました。再びpyimage2が存在しないことに加えて、ルートフレームのキャンバスが空白になります。

tkinter がガベージを処理する方法についてのコメントを読んだことがありますが、これが関連している可能性があります。画像には 2 番目の参照を添付する必要があるというコメントも読みましたが、このアクションを実装する方法はまだわかりません。

これは tkinter 内で行うことができますか、代わりに枕の使用を検討する必要がありますか?

サンプル コード、オリジナルのはるかに長いものを含めます。

このコードはルート ウィンドウのメニューから呼び出され、ローカルの日付と時刻の情報を表示するためのものです。私は現在のムーンフェイズも含めて写真を撮ろうとしていました:

def date_time():
    date_time_window = Tk()
    date_time_window.title('Date & Time')
    date_time_window.geometry('650x350')

    # Widgets

    present_date = today

    main_heading = Label(date_time_window, text = 'Date & Time')
    line1 = Canvas(date_time_window, width = 650, height = 3)
    line1.create_line(0,2 , 650,2, width = 1, fill = 'cyan')
    date_txt = Label(date_time_window,text = 'Date: ')
    date_value = Label(date_time_window, text =  today.strftime('%d') + '/' +       today.strftime('%m') + '/' + today.strftime('%y'))
    time_utc_txt = Label(date_time_window, text = 'UTC Time:')
    time_utc_value = Label(date_time_window, text = str(datetime.utcnow())[11:19])
    dls_txt = Label(date_time_window, text = 'DLS on/off: ')

    if moon_phase_number == 0:
        moon_photo = PhotoImage( file = 'images\moon_phase_0.gif')
    elif moon_phase_number == 1:
        moon_photo = PhotoImage( file = 'images\moon_phase_1.gif')


    canvas = Canvas(date_time_window, width = 200, height = 200, bg = 'yellow')        
    canvas.create_image(0, 0, image = moon_photo, anchor = NW)

    canvas.place( x = 300, y = 150)

    close_btn.configure( command = date_time_window.destroy)

    date_time_window.mainloop()
4

1 に答える 1

1

SSCCE なしで提供されたコード サンプルをデバッグすることはできませんが、残りの質問には十分に答えられるように努めます。


一度に複数のフレームで画像を表示することはできますか?

はい、画像を含むフレームの数に特に制限はありません。


画像には 2 番目の参照を添付する必要があるというコメントも読みましたが、このアクションを実装する方法はまだわかりません。

そのコメントは、おそらくこのドキュメントを参照していました。

注: PhotoImage オブジェクトが Python によってガベージ コレクションされると (たとえば、ローカル変数に画像を保存した関数から戻るとき)、画像は Tkinter ウィジェットによって表示されていてもクリアされます。

これを回避するために、プログラムは画像オブジェクトへの余分な参照を保持する必要があります。これを行う簡単な方法は、次のように画像をウィジェット属性に割り当てることです。

label = Label(image=photo)
label.image = photo # keep a reference!
label.pack()

同様に、moon_photoウィジェットの 1 つにアタッチする必要があります。canvas.image = moonphotoで十分でしょう。


これはtkinter内で行うことができますか、代わりに枕の使用を検討する必要がありますか?

PhotoImage は gif および pgm 画像しか表示できないため、画像の表示には一般的に PIL/Pillow をお勧めします。PIL のImageTk.PhotoImageクラスは、さらに多くの種類の形式をサポートしています。ただし、ここでは gif をレンダリングするだけなので、Tkinter 以外は必要ありません。

于 2014-06-26T14:56:52.337 に答える