前提・実現したいこと
クイズゲームを作成しています。
取り込んだcsvの要素をランダムに選び、同じ要素を答えさせるゲームはいったん完成したため
新たにランダムに植物の画像を表示し、その植物の名前を当てるゲームを考えています。
※csvは以下のようなイメージです。
[{'name': 'ススキ', 'family': 'イネ科', '画像': 'ine.jpg'},
{'name': 'コムギ', 'family': 'イネ科', '画像': 'komugi.jpg'},…
ラベルに画像を表示させる(まだ固定ファイル名)ことはなんとかできたのですが、
1.その画像をリサイズする処理がうまくいきません。
リサイズ処理のみ動かした場合、うまくいったプログラムを移植したのですが・・・
2.画像をランダムに選択するため、画像読み込みの部分を関数init_view(tki)内に入れたいのですが
テスト的に固定ファイル名を指定した状態でも、まともに表示できません。
特に2に関してはラベルの理解が甘いのだと思うのですが、調べてはみたものの
ラベルの扱いも画像表示の手法も人によってさまざまで、前に進まなくなってきました。
発生している問題・エラーメッセージ
1.について _tkinter.TclError: image specification must contain an odd number of elements
該当のソースコード
python3.8.0
import random import csv import tkinter, tkinter.messagebox from tkinter import * from tkinter import ttk tki = None rdo = None b_options = None rdo_var = None answer = None def init_view(tki): global rdo, b_options, rdo_var, answer # 上記DictReaderで読み込んだ辞書リストから、問題用に、ひとつの辞書を呼び出す p_plant = random.choice(rows) print(p_plant) p_name = p_plant["name"] # 問題用の植物と同じ科(family)の植物をリストにして、 # その中から問題用の植物を削除。 # 残りからひとつを選ぶ(=その植物が答えになる) q_list = [] while len(q_list) < 2: q_list = [x['name'] for x in rows if x['family'] == p_plant["family"]] q_list.remove(p_plant["name"]) answer = random.choice(q_list) # 答えとは異なる科(family)の植物をリスト化し、そこから3つ選ぶ b_list = [x['name'] for x in rows if x['family'] != p_plant["family"]] b_options = random.sample(b_list , 3) b_options.append(str(answer)) random.shuffle(b_options) # 配置済みの子ウィジェットが存在すれば、削除しておく children = tki.winfo_children() for child in children: # print("type of widget is : " + str(type(child))) if str(type(child)) == "<class 'tkinter.Radiobutton'>": child.destroy() elif str(type(child)) == "<class 'tkinter.Button'>": child.destroy() elif str(type(child)) == "<class 'tkinter.Label'>": child.destroy() # ラジオボタンのラベルをリスト化する # rdo_txt = random.sample(b_options , k=4) # ラジオボタンの状態 rdo_var = tkinter.IntVar() # ラジオボタンを動的に作成して配置 for i in range(4): rdo = tkinter.Radiobutton(tki, value=i, variable=rdo_var, text=b_options[i]) rdo.place(x=50, y=80 + (i * 24)) # ボタン作成 btn = tkinter.Button(tki, text='答え合わせ', command=btn_click) btn.place(x=100, y=270) # 以前画像を使わない4択問題で使っていたコード # var = tkinter.StringVar() # var.set(p_name + "と同じ科の植物はどれでしょう") # label = tkinter.Label(tki, image=icon,textvariable=var, compound="top",width=100, ) # label.pack() # ボタンクリックイベント def btn_click(): num = rdo_var.get() if b_options[num] == str(answer): tkinter.messagebox.showinfo('結果' , "正解!") else: tkinter.messagebox.showinfo("結果" , '不正解!正解は' + answer) # 表示内容の再初期化 init_view(tki) with open('plant.csv', newline='') as csvfile: reader = csv.DictReader(csvfile) rows = [] for row in reader: rows.append(row) root = Tk() root.geometry('300x400') root.title('ラジオボタン') frame1 = ttk.Frame(root) frame1.grid() # ここが困っている部分です icon = PhotoImage(file="aburana_f.gif") label1 = ttk.Label(frame1 , image=icon , text="てきすと", compound="top") label1.grid(row=1,column=1) root.mainloop()
試したこと
1.について
img = Image.open("daikon_f.jpg") # イメージを開く
resize_image = img.resize((200, int(200 * img.size[1] / img.size[0]))) # 画像のリサイズ
2.について
icon = PhotoImage(file="aburana_f.gif")
label1 = ttk.Label(frame1 , image=icon , text="てきすと", compound="top")
label1.grid(row=1,column=1)
を
ボタン作成の下に入れ、多少いじりましたが、ウィンドウは出るものの、画像もボタンも何も表示されません。
補足情報(FW/ツールのバージョンなど)
ここにより詳細な情報を記載してください。
まだ回答がついていません
会員登録して回答してみよう