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

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

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

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

Q&A

解決済

2回答

778閲覧

だれがどこで何をしたゲームを作りたい。

amatou

総合スコア2

Python

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

0グッド

0クリップ

投稿2023/04/05 12:10

したいこと

PysimpleGUIで、ボタンを押すとランダムに「Aが○○でバ☓☓をした」や「Cが□□で**をした」のように表示させたいです。

前提

本を用いて勉強していましたが分からないことがあったので質問しました。
使用しているのはPysimpleGUIです。
レイアウトは完成しました。

発生している問題

本来ボタンを押すと反応があるはずなのですがボタンを押しても、文字が表示されないです。
エラーは無いので、おそらく何かが抜けているのだと思います。

該当のソースコード

PysimpleGUI

1import PySimpleGUI as sg 2import random 3sg.theme("Darkbrown3") 4 5layout = [[sg.T(k="txt")], 6 [sg.B("だれが",k="btn0"), 7 sg.B("どこで",k="btn1"), 8 sg.B("何をした",k="btn2")]] 9win = sg.Window("だれがどこで何をしたゲーム",layout,font=(None,14)) 10 11who = ["A","B","C"] 12Conjunction= ["が"] 13Where= ["○○で","□□で","△△で"] 14do =["☓☓した","**した","--した"] 15 16def execute(): 17 txt = values["btn0"] + values["btn1"] + values["btn2"] 18 window["txt"].update(txt) 19 20while True: 21 event,values= win.read() 22 if event == 'だれが': 23 random.choice(who) + random.choice(Conjunction) 24 if event == 'どこで': 25 random.choice(Where) 26 if event == '何をした': 27 random.choice(do) 28 if event == None: 29 break 30 31window.close()

試したこと

・□□などの記号が使えないのかと思い、文字にしてみた。
・if eventではなく、if eにした。
・if event ==ではなく、if event =にした。
・if eventではなく、if valuesにした。

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

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

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

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

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

guest

回答2

0

ベストアンサー

PySimpleGUIの基本的な使いかたが、今一つ把握できていないように思います。

以下、今回の説明に特化してざっくり説明します。

前にも書きましたが、GUIのプログラムでは、プログラム実行中はすべてイベントをきっかけとしてすべてのことが動作します。 イベントというのは、ボタンを押したり、キーボードのキーを押したりすることなどです。
PySimpleGUIでは、whileで作った無限ループの中で、Window.read()を呼ぶことで発生したイベントを取得することができます。 このプログラムでは、 sg.Windowのインスタンスはwinになっています。

python

1while True: 2 event, values = win.read()

このとき、 eventには、ウィジェット(Buttonなど)の定義で keyにしていしたものが入ってきます。なので、ボタンが押されたときには、"だれが'とかではなく**'btn0'**などが入ってきます。なので、質問のif文は間違えています。 また、 if文はいずれかになるので、elifにしたほうがわかりやすいでしょう。
一部書き換えるとこうなりますが、

python

1 if event == 'btn0': 2 random.choice(who) + random.choice(Conjunction) 3 elif event == 'btn1': 4 random.choice(Where) 5 elif event == 'btn2': 6 random.choice(do)

さて、if文の中で、文をランダムに選んでいますが、これでは選んでいるだけで、何も起きません
random.choice(Where) としても、Whereの中から1つ選ばれますが、どこにも保存されずに捨てられてしまうのです。
以下のexecute関数でそれを使おうとしているのかもしれませんが、その関数はどこからも呼ばれませんし、また、中で参照しているvaluesもwhileループの中でのみ意味のある値を持つ変数なので、ここで使うのは適切ではありません。

python

1def execute(): 2 txt = values["btn0"] + values["btn1"] + values["btn2"] 3 win["txt"].update(txt)

直すとしたらこんな感じでしょうか。

  • 表示するwho, when, do の値を持つ変数を用意しておく。
  • ボタンが押されたときは、その値を変更する。

としましょう。 こうすることで、ボタンを押したときに選んだ値を保持できます。
あとは、textエリアに文章を追加する必要がありますね。 いずれかのボタンが押されて文字が変更になったときに実行すればいいので、

  • execute()を変数を使うように変更する。
  • 各ボタンの処理の後でexecuteを呼ぶ

ということにします。
これで修正するとこんな感じです。

python

1import PySimpleGUI as sg 2import random 3sg.theme("Darkbrown3") 4 5layout = [[sg.Text(key="txt")], 6 [sg.Button("だれが",key="btn0"), 7 sg.Button("どこで",key="btn1"), 8 sg.Button("何をした",key="btn2")]] 9win = sg.Window("だれがどこで何をしたゲーム",layout,font=(None,14)) 10 11who = ["A","B","C"] 12conjunction= ["が"] 13where= ["○○で","□□で","△△で"] 14do =["☓☓した","**した","--した"] 15 16who_str = "WHO" 17where_str = "WHERE" 18do_str = "DO" 19 20def execute(): 21 txt = f'{who_str} {where_str} {do_str}' 22 win['txt'].update(txt) 23 24while True: 25 event,values= win.read() 26 if event == 'btn0': 27 who_str = random.choice(who) + random.choice(conjunction) 28 execute() 29 elif event == 'btn1': 30 where_str = random.choice(where) 31 execute() 32 elif event == 'btn2': 33 do_str = random.choice(do) 34 execute() 35 elif event == sg.WIN_CLOSED: 36 break

おまけ

前にtkinterで作っていたものを、PySimpleGUIで作りなおすことにしたのかはわかりませんが、少し簡単になっているとは言っても、GUIのプログラムの動作の基本というのは変りません。イベントはすべてループの中で処理しなければなりませんし、ループの外の処理は、ループの前後でしか実行されません。
また、質問のexecute関数関数のように、関数は明示的に呼ぶようにしなければ勝手に使われることは(通常は)ありません。


おまけ その2

作ったプログラムが動かないとき、何をしていますか?

たとえば、質問のコードでは、ボタンを押しても何も起きませんでしたが、何をしていますか?
そういう問題(バグ)の原因をみつけて取り除くことをデバッグと言います。 デバッグの原始的なものの1つにprintデバッグと呼ばれる手法があります。
"だれが"を押したときに、if文の"だれが" のところに入るはずですよね。 その動作がおかしいのであれば、そのif文の中にprint("だれがに入った!")などを追加して動かしてみるのです。 ボタンを押してそれが表示されれば、その動作はOKで、じゃあ、問題はその中にあるから... というように処理を追い掛けていくことができるのです。
質問のコードはまずは、このif文の中に入りません。 ということは、判定が間違えている、じゃあ、eventには何が入っているかprint()してみよう.. といったことをすれば、 eventには "だれが"ではなく、'btn0'などが入っていることがわかるでしょう。
地道な作業ですが、こういうことを積み重ねることで、だんだんプログラミングのスキルは上っていくものです。

投稿2023/04/05 14:00

TakaiY

総合スコア12657

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

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

amatou

2023/04/05 22:57

ありがとうございます!デバッグにもチャレンジしてみます!
guest

0

python

1import PySimpleGUI as sg 2import random 3 4sg.theme("Darkbrown3") 5 6layout = [[sg.T(k="txt")], 7 [sg.B("だれが",k="btn0"), 8 sg.B("どこで",k="btn1"), 9 sg.B("何をした",k="btn2")]] 10win = sg.Window("だれがどこで何をしたゲーム",layout,font=(None,14)) 11 12who = ["A","B","C"] 13Conjunction = ["が"] 14Where = ["○○で","□□で","△△で"] 15do = ["☓☓した","**した","--した"] 16 17who_text, where_text, what_text = '', '', '' 18while True: 19 event, values = win.read() 20 if event == 'btn0': 21 who_text = random.choice(who) + random.choice(Conjunction) 22 if event == 'btn1': 23 where_text = random.choice(Where) 24 if event == 'btn2': 25 what_text = random.choice(do) 26 if event == None: 27 break 28 29 win['txt'].update(who_text + where_text + what_text) 30 31win.close()

投稿2023/04/05 12:45

melian

総合スコア19618

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

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

amatou

2023/04/05 22:58

ありがとうございます(._.)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問