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

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

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

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

Python

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

Q&A

解決済

1回答

1966閲覧

tkinterでフレーム上の画像が表示されない

退会済みユーザー

退会済みユーザー

総合スコア0

Tkinter

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

Python

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

0グッド

0クリップ

投稿2020/02/04 14:14

前提・実現したいこと

pythonでクイズゲームを作成しています。
あらかじめクイズのネタとなる植物の情報をcsvにまとめ、
[{'name': 'ススキ', 'family': 'イネ科', 'sevenherbs': '対象外', 'flower': 'jagaimo_f.jpg'},
{'name': 'コムギ', 'family': 'イネ科', 'sevenherbs': '対象外', 'flower': 'komugi_p.jpg'},
これをもとにランダムにクイズを出すイメージです。
1.同じ科の植物を当てる
2.表示されている写真の植物を当てる
の2パターンを作成しているのですが、
2の写真が表示されません。
問題を変えるたびに枠が伸び縮みしているのでデータは読み込んではいると思うのですが、
絵が見えず、地のグレーのままになってしまいます。

発生している問題・エラーメッセージ

なにもエラーメッセージは出ていないのですが 画像だけ表示されません。

該当のソースコード

python3.8.0

1#ラベルフレームの使い方 2import tkinter as tk 3import random 4import csv 5import tkinter, tkinter.messagebox 6from tkinter import ttk 7from PIL import Image , ImageTk 8 9rdo = None 10b_options = [1 ,2 ,3, 4] 11rdo_var = None 12answer = None 13icon_label = None 14toggle = None 15picture = "aburana_f.gif" 16 17def init_view(tki): 18 global rdo, b_options, rdo_var, answer , icon_label , picture 19 Q = random.randint(1,2) 20 21 # DictReaderで読み込んだ辞書リストから、問題用に、ひとつの辞書を呼び出す 22 p_plant = random.choice(rows) 23 print(p_plant) 24 25 if Q == 1: 26 # 問題用の植物と同じ科(family)の植物をリストにして、 27 # その中から問題用の植物を削除。残りからひとつを選ぶ(=その植物が答えになる 28 29 q_list = [] 30 while len(q_list) < 2: 31 q_list = [x['name'] for x in rows if x['family'] == p_plant["family"]] 32 q_list.remove(p_plant["name"]) 33 answer = random.choice(q_list) 34 35 # 答えとは異なる科(family)の植物をリスト化し、そこから3つ選ぶ 36 b_list = [x['name'] for x in rows if x['family'] != p_plant["family"]] 37 exam = p_plant["name"] + "と同じ科の植物はどれでしょう" 38 picture = p_plant["flower"] 39 40 elif Q == 2: 41 #絵を見て植物を当てる問題 42 answer = p_plant["name"] 43 b_list = [x['name'] for x in rows if x['name'] != p_plant["name"]] 44 exam = "これはなんという植物でしょう" 45 picture = p_plant["flower"] 46 47 48 # ここから共通のプログラム 49 b_options = random.sample(b_list , 3) 50 b_options.append(str(answer)) 51 random.shuffle(b_options) 52 print(exam) 53 54 # 配置済みの子ウィジェットが存在すれば、削除しておく 55 # すごく不格好なのでスリムにしたい・・・ 56 children = frame_2.winfo_children() 57 for child in children: 58 print("type of widget is : " + str(type(child))) 59 if str(type(child)) == "<class 'tkinter.Radiobutton'>": 60 child.destroy() 61 62 children = frame_1.winfo_children() 63 for child in children: 64 print("type of widget is : " + str(type(child))) 65 if str(type(child)) == "<class 'tkinter.Label'>": 66 child.destroy() 67 68 children = frame.winfo_children() 69 for child in children: 70 print("type of widget is : " + str(type(child))) 71 if str(type(child)) == "<class 'tkinter.Label'>": 72 child.destroy() 73 74 #選択肢の作成 75 for i in range(4): 76 rdo = tk.Radiobutton(frame_2, value=i, variable=var, text=b_options[i] ) 77 rdo.place(x=50, y=30 + (i * 24)) 78 rdo.pack() 79 80 #問題文の表示 81 text_str=tk.StringVar() 82 text_str.set(str(exam)) 83 text=tk.Label(frame_1,textvariable=text_str) 84 text.pack() 85 86 #■■■■■■ここが困っています■■■■■■ 87 img = Image.open(picture) 88 resize_img = img.resize((300, int(300 * img.size[1] / img.size[0]))) 89 img_f = ImageTk.PhotoImage(resize_img) 90 label1 = tk.Label(frame , image= img_f, text="てきすと") 91 label1.pack() 92 93 94#ウインド画面の作成 95root=tk.Tk() 96root.title("植物クイズ") 97root.geometry("600x500") 98 99#フレームの作成 100#フレーム1(左) 101frame=tk.LabelFrame(root,text="画像",foreground="green") 102frame.grid(row=0,column=0 , rowspan=2) 103#フレーム2(右上) 104frame_1=tk.LabelFrame(root,text="問題文",foreground="green") 105frame_1.grid(row=0,column=1) 106#フレーム3(右下) 107frame_2=tk.LabelFrame(root,text="選択肢",foreground="green") 108frame_2.grid(row=1,column=1) 109#フレーム4(下) 110frame_3=tk.LabelFrame(root,text="",foreground="green") 111frame_3.grid(row=2,columnspan=2) 112 113#ラジオボタンの作成(フレーム1に作成) 114var=tk.IntVar() 115var.set(0) 116 117 118 119#テキストの作成(フレーム4に作成) 120text_str=tk.StringVar() 121text_str.set("ボタンを押して下さい") 122text=tk.Label(frame_3,textvariable=text_str) 123text.pack() 124 125#ボタンを押したときに動作する関数 126def check(): 127 num = var.get() 128 129 if b_options[num] == str(answer): 130 tkinter.messagebox.showinfo('結果' , "正解!") 131 else: 132 tkinter.messagebox.showinfo("結果" , '不正解!正解は' + answer) 133 init_view(root) 134 135#ボタンの作成(フレーム4に作成) 136Button=tk.Button(frame_3,text="答え合わせ",command=check) 137Button.pack() 138 139with open('plant2.csv', newline='') as csvfile: 140 reader = csv.DictReader(csvfile) 141 rows = [] 142 for row in reader: 143 rows.append(row) 144 145init_view(root) 146 147#画面の表示 148root.mainloop() 149 150

試したこと

はじめは「フレームの作成」のすぐ下で記述し、
動作することを確認していましたが、
動的にするため関数init_viewの中に入れると表示されなくなってしまいました。

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

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

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

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

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

guest

回答1

0

ベストアンサー

現状のコードでは、PhotoImageを保持している img_f変数がローカル変数の為、init_view()を抜けた瞬間にPhotoImage自体が破棄されてしまうのが不具合の原因です。
(つまり画像が一瞬表示されて、直ぐに破棄されて消えるという処理が行われているということです)

対策としては、init_view() 関数先頭の global宣言に img_fを追加すると良いかと思います。

Pyhtnon

1def init_view(tki): 2 global rdo, b_options, rdo_var, answer , icon_label , picture , img_f

投稿2020/02/05 00:42

magichan

総合スコア15898

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

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

退会済みユーザー

退会済みユーザー

2020/02/05 11:53

ありがとうございました。うまく動きました。 エラーが出ないため、特定する手掛かりがなく困っていました。助かりました。 しかしPhotoImageってリサイズも手間だし扱いにくいですね・・・
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問