質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

10356閲覧

Tkinterで画像の切り替えができない

jun_endo

総合スコア56

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2018/10/10 06:27

編集2018/10/10 07:03

#GUIを使って画像を表示させたい

Tkinterを使って、カスケード分類器の画像を表示させたいのですが、
画像をファイル選択画面で、選んだ画像をCanvasに表示させたいので、
表示している画像を変更したいと思いました。

#起動した段階で、デフォルトで画像がすでに表示されている。
勉強しながら、コーディングをしていたので、
GUIが表示されている時点で、もうすでに一つ画像が表示されている状態です。
その状態から、切り替えをしたいのです。

#画像
sideface
sideface.jpg

test4
test4.png

#プログラムの動き
GUIが表示されると、デフォで画像がcanvas_1に表示してあります。
GUIのボタンに[参照]ボタンがあります。
そのボタンを押すと、任氏の画像を選択する画面が表示されます。
選択し終えたら、終了したと同時に、
canvas_1に選択した画像が表示されるようにしたい。

#プログラム

python

1import os, sys 2import tkinter as tk 3from tkinter import * 4from tkinter import filedialog 5from tkinter import messagebox 6from typing import Optional, Any 7 8from PIL import Image, ImageTk 9 10on_canvas = None 11 12# 参照ボタンのイベント 13# button1クリック時の処理 14def button1_clicked(): 15 fTyp = [("画像ファイル[jpg(jpeg),png,ppm]", "*.png;*.jpg;*.jpeg;*.ppm")] 16 iDir = os.path.abspath(os.path.dirname(__file__)) 17 filepath = filedialog.askopenfilename( 18 filetypes=fTyp, 19 initialdir=iDir 20 ) 21 file1.set(filepath) 22 image = Image.open(filepath) 23 img = ImageTk.PhotoImage(image) 24 on_camvas = canvas_1.create_image( 25 0, 26 0, 27 image=img, 28 anchor=tk.NW 29 ) 30# button2クリック時の処理 31def button2_clicked(): 32 #省略 33 34 35if __name__ == '__main__': 36 global on_canvas 37 # rootの作成 38 root = Tk() 39 root.geometry("1000x400") 40 root.title('machine learning') 41 root.resizable(False, False) 42 43 # Frame1の作成 44 frame1 = tk.Frame(root, width=400, height=70) 45 frame1.place(x=0, y=0) 46 47 # Frame2の作成 48 frame2 = tk.Frame(root, width=270, height=100) 49 frame2.place(x=0, y=30) 50 51 # Frame3の作成 52 frame3 = tk.Frame(root, width=620, height=362) 53 frame3.place(x=369, y=0) 54 55 canvas_1 = tk.Canvas( 56 frame3, 57 width=300, 58 height=300, 59 relief=tk.RIDGE, 60 bd=3, 61 bg="white" 62 ) 63 canvas_1.place(x=1, y=50) 64 image2 = Image.open("sideface.jpg") 65 img2 = ImageTk.PhotoImage(image2) 66 on_canvas = canvas_1.create_image( 67 0, 68 0, 69 image=img2, 70 anchor=tk.NW 71 ) 72 73 #参照ボタンの作成 74 button1 = tk.Button( 75 frame1, 76 text=u'[参照]', 77 command=button1_clicked, 78 width=10 79 ) 80 button1.place(x=283, y=35) 81 # 「ファイル」ラベルの作成 82 s = StringVar() 83 s.set('ファイル>>') 84 label1 = tk.Label(frame1, textvariable=s) 85 label1.place(x=0, y=5) 86 87 # 参照ファイルパス表示ラベルの作成 88 file1 = StringVar() 89 file1_entry = tk.Entry( 90 frame1, 91 textvariable=file1, 92 width=50 93 ) 94 file1_entry.place(x=57, y=7) 95 96 97 # Startボタンの作成 98 button2 = tk.Button( 99 frame2, 100 text='[Start]', 101 command=button2_clicked, 102 width=10 103 ) 104 button2.place(x=10, y=6) 105 106 # Cancelボタンの作成 107 button3 = tk.Button( 108 frame2, 109 text='[Cancel]', 110 command=quit, 111 width=10 112 ) 113 button3.place(x=100, y=6) 114 115 116 117 lb = StringVar() 118 lb.set("Before") 119 label_before = tk.Label(frame3, textvariable=lb, font=30) 120 label_before.place(x=0, y=0) 121 122 la = StringVar() 123 la.set("After") 124 label_after = tk.Label(frame3, textvariable=la, font=30) 125 label_after.place(x=308, y=0) 126 127 canvas_2 = tk.Canvas( 128 frame3, 129 width=300, 130 height=300, 131 relief=tk.RIDGE, 132 bd=3, 133 bg="white" 134 ) 135 136 canvas_2.place(x=308, y=50) 137 138 139 root.mainloop() 140 141

#試してみたこと
タグ付けして、一度deleteしてから、
再度、create_imageをしてみたが、
変更されませんでした。(厳密には、デフォの画像が無くなり、何も表示されなくなった)

#変更箇所

python

1def button1_clicked():内のcanvas_1部分を 2 3 canvas_1.delete("bef")#追加 4 canvas_1.create_image( 5 0, 6 0, 7 image=img, 8 anchor=tk.NW, 9 tag="bef"#追加 10 ) 11if __name__ == '__main__':内のcanvas部分を 12 canvas_1.create_image( 13 0, 14 0, 15 image=img2, 16 anchor=tk.NW, 17 tag="bef"#追加 18 )

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

button1_clicked関数内の変数:imgがローカル変数なため、GC(GarbageCollection)対象になり、そのため画像が消えてしまうかと。
◆GC対象になる原因
PythonインタプリタがGC実行時にGCルートから参照を辿れないのが原因です。

◆対応案 (上からオススメ順です)
案1, CanvasからLabalに変更し、Labelに画像(img)の参照を持つ。
Tkinter - tkinter.PhotoImageがttk.Label上に表示されない | qiita.com
この変更を行う事でLabelから参照を辿れます。
案2, 変数:imgをグローバル変数に変更する。

◆参考

ページの左下の図がGCの動作の概念図です。イメージ説明

投稿2018/10/10 07:24

編集2018/10/10 10:35
umyu

総合スコア5846

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jun_endo

2018/10/10 07:42

ありがとうございました! 案2でやったところ、一行で解決しました!ありがとうございました!
guest

0

描画するオブジェクトに「tag」をつけ、それをキーに削除イベントを走らせるといかがでしょうか?

【Python】Tkinterのcanvasを使ってみる

投稿2018/10/10 06:30

編集2018/10/10 06:31
nnahito

総合スコア2004

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jun_endo

2018/10/10 07:06 編集

ダメでした。 初期のプログラムを作成した以前のプログラムにも、 同じ現象がありました。 デフォルトの画像が表示されなくなりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問