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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

990閲覧

Pythonでjpg画像を二枚表示し、ボタンでそれぞれ異なる画像を表示したいのです。

退会済みユーザー

退会済みユーザー

総合スコア0

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2020/09/12 07:33

前提・実現したいこと

Pythonでjpg画像を二枚表示し、ボタンでそれぞれ異なる画像を表示したいのです。

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

コマンドボタンをクリックしたら上下の画像を違う画像に切り替えたいのでが、現在は上側の画像のみが変わります。 また一度使用した画像はリストから削除したのですが、うまく行きません。   flower = flowers.pop() で取り出してその画像ファイルは削除したいのですが、codingが良く分かりません。 一枚だけの画像だと上手く切り替わりますが、二画像だと画像fileがreturnで上手く引き渡せていないか、廃棄されてしまうのかもしれません。 宜しくお願い致します。

該当のソースコード

Python3.7.3

1import tkinter as tk 2import random 3from PIL import Image, ImageTk 4 5root = tk.Tk() 6root.geometry('300x500') 7 8flowers = ['カタバミ.jpg', 'カンパニューラ.jpg', 'クレオメ.jpg', 9 'クンシラン.jpg', 'ジキタリス.jpg', 'シューカイドウ.jpg', ] 10 11 12def select_img_file(): 13 flower = random.sample(flowers, 2) 14 photo_file = flower 15 photo_file = photo_file[0] 16 photo_file = flower 17 photo_file = photo_file[1] 18 19 return photo_file 20 21 22def push_next_button(event): 23 img_next = Image.open(select_img_file()) 24 img_next = ImageTk.PhotoImage(img_next) 25 label1.configure(image=img_next) 26 label1.photo = img_next 27 28 29# run時に一回だけ動作する 30img = Image.open(select_img_file()) 31img = ImageTk.PhotoImage(img) 32 33label1 = tk.Label(root, image=img) 34label1.place(x=40, y=30) 35 36label2 = tk.Label(root, image=img) 37label2.place(x=40, y=250) 38 39 40btn1 = tk.Button(root, text='次へ') 41btn1.place(x=50, y=450) 42btn1.bind("<1>", push_next_button) 43 44def destroy(): 45 root.destroy() 46 47btn2 = tk.Button(root, text='終わる', command=destroy) 48btn2.place(x=150, y=450) 49 50root.mainloop()

試したこと

変数をglobalにしたり、select_img_file(): を二つ作ったりしましたが、私の実力では解決できませんでした。

codeを変更したりしても、上下が入れ替わるくらいで、うまく行きませんでした。 

補足情報(FW/ツールのバージョンなど)

開発環境はW10 x64、Visual Sutudio Codeを使用しております。

出来上がり図と必要画像を添付致します。画像はpyファイルと同じholderにあります。

![イメージ説明
イメージ説明

イメージ説明
イメージ説明
イメージ説明
イメージ説明
イメージ説明
イメージ説明

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

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

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

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

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

guest

回答1

0

ベストアンサー

以下のコードですが、同じ変数に対して値を複数回代入した場合、一番最後に代入したものが残ります。

python

1def select_img_file(): 2 flower = random.sample(flowers, 2) 3 photo_file = flower 4 photo_file = photo_file[0] 5 photo_file = flower # すでに記録されていた photo_file[0] の情報が消える 6 photo_file = photo_file[1] 7 8 return photo_file

つまり、このコードは以下と同じであり、2枚の画像パスを返すという処理になっていません。

python

1def select_img_file(): 2 flower = random.sample(flowers, 2) 3 photo_file = flower 4 photo_file = photo_file[1] 5 6 return photo_file

python

1a = 1 2a = 2 # 2を代入したら、すでに記録されていた1という値の情報は消える 3print(a) # 2

リストから値を一つ取り出しすというのは list.pop() が利用できます。
この関数はリストの末尾の値を1つ取り出して、それをリストから削除します。
なので、pop() を何回も呼び出せば、1度使った値はリストから削除していくということが実現できます。

python

1lst = [1, 2, 3] 2 3v = lst.pop() # 末尾から1つ取り出す 4print(v, lst) # 3 [1, 2] 5v = lst.pop() # 末尾から1つ取り出す 6print(v, lst) # 2 [1] 7v = lst.pop() # 末尾から1つ取り出す 8print(v, lst) # 1 []

サンプルコード

上記の点を踏まえて以下のように修正してみました。

python

1import tkinter as tk 2from tkinter import messagebox 3import random 4from PIL import Image, ImageTk 5 6root = tk.Tk() 7root.geometry("300x500") 8 9flowers = [ 10 "カタバミ.jpg", 11 "カンパニューラ.jpg", 12 "クレオメ.jpg", 13 "クンシラン.jpg", 14 "ジキタリス.jpg", 15 "シューカイドウ.jpg", 16] 17 18# シャッフルしておく。 19random.shuffle(flowers) 20 21 22def get_img(): 23 # 画像を1枚取り出す。取り出した画像は flower から削除される。 24 img_path = flowers.pop() 25 # 画像を読み込む。 26 img = Image.open(img_path) 27 # リサイズする。 28 img.thumbnail((200, 200)) 29 # ImageTk.PhotoImage オブジェクトに変換する。 30 img = ImageTk.PhotoImage(img) 31 32 return img 33 34 35def setup_images(): 36 """2枚の画像をラベルに設定する。 37 """ 38 img = get_img() 39 label1.configure(image=img) 40 label1.photo = img 41 42 img = get_img() 43 label2.configure(image=img) 44 label2.photo = img 45 46 47def push_next_button(event): 48 """「次へ」ボタンが押されたときに呼ばれる関数 49 """ 50 51 # 画像が空の場合 52 if not flowers: 53 # メッセージボックスを表示 54 messagebox.showinfo("警告", "これ以上表示する画像がありません") 55 return 56 57 setup_images() 58 59 60# run時に一回だけ動作する 61label1 = tk.Label(root) 62label1.place(x=40, y=30) 63 64label2 = tk.Label(root) 65label2.place(x=40, y=250) 66 67# 画像を設定する。 68setup_images() 69 70btn1 = tk.Button(root, text="次へ") 71btn1.place(x=50, y=450) 72btn1.bind("<1>", push_next_button) 73 74 75def destroy(): 76 root.destroy() 77 78 79btn2 = tk.Button(root, text="終わる", command=destroy) 80btn2.place(x=150, y=450) 81 82root.mainloop() 83

投稿2020/09/12 09:03

編集2020/09/12 09:04
tiitoi

総合スコア21956

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

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

退会済みユーザー

退会済みユーザー

2020/09/12 10:15

tiitoriさん いつも素晴らしい解決案を教えて頂き有難うございます。 def get_img():を呼び出すようにするのですね、分かりました。 実はブラックジャックを作ってまして、トランプを親と子に配布するところで停滞しておりました。 今回のアドバイスを基にチャレンジしてみます。 その時にまたお世話になるかもしれませんが、宜しくお願い致します。 今日は良い夢を見られそうです、有難うございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問