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

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

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

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

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Python

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

Q&A

解決済

2回答

1934閲覧

Shellで実行されるコードを、tkinter ボタンに割り当て実行しようとしたのですが、うまくいきません

swing

総合スコア3

Tkinter

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

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Python

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

0グッド

0クリップ

投稿2020/05/06 03:33

下記、プログラムをShellで実行すると問題なく動きます。内容は、
➀、質問に対して、OKなら表示されているランダムな数字を入力して、OKボタンを押す
➁、同じ数字が入力されていれば、リスト内の次の質問と次の(ランダムな)数字が表示される
➂、異なる数字が入力されれば、再度、同じ質問と先ほどとは異なる数字が表示される

python

1import random 2 3q=["Aでいいですか?","Bでもいいですか?","Cでもいいですよね?"] 4q.append("Dも追加していいですか?") 5 6g=len(q) 7n=0 8 9while True : 10 print(q[n]) 11 a=random.randint(0,100) 12 print(a) 13 b=int(input("""OKなら同じ数字を入力してください 14→""")) 15 16 if a!=b: 17 continue 18 else: 19 n=(n+1)% g

実行しますとShellで下記のように表示されます
~・~・~・~・~・~・~・~・~・~・~・~・~・~・
Aでいいですか?
8
OKなら同じ数字を入力してください
→8
Bでもいいですか?
55
OKなら同じ数字を入力してください
→55
Cでもいいですよね?
19
OKなら同じ数字を入力してください
→19
Dも追加していいですか?
21
OKなら同じ数字を入力してください
→21
Aでいいですか?
~・~・~・~・~・~・~・~・~・~・~・~・~・~・

これをtkinterを使って再現したく、ネットにあった構文を拝借して、上記のコードを各所の思う所に当て込んで下記のように実行すると、
「line 45, in <module>
if a != c:
NameError: name 'c' is not defined」
と、エラーになります。

python

1import tkinter as tk 2import random 3 4 5# ウィンドウを作成 6win = tk.Tk() 7win.title("質問") 8win.geometry("500x250") 9 10# 部品を作成 11label1 = tk.Label(win, text="----") 12label1.pack() 13 14label2 = tk.Label(win, text="----") 15label2.pack() 16 17label3 = tk.Label(win, text="OKなら同じ数字を入力してokを押してください") 18label3.pack() 19 20text1 = tk.Entry(win) 21text1.insert(tk.END, '') 22text1.pack() 23 24# 作業を作製 25q=["Aでいいですか?","Bでもいいですか?","Cでもいいですよね?"] 26q.append("Dも追加していいですか?") 27 28g=len(q) 29n=0 30 31while True : 32 label1["text"]=q[n] 33 a=random.randint(0,100) 34 label2["text"]=a 35 36 def ok_click(): 37 c= int(text1.get()) 38 39 if a != c: 40 continue 41 else: 42 n=(n+1)% g 43 44 45 46# ボタンを作成 47okButton = tk.Button(win, text='ok',command=ok_click) 48okButton.pack() 49 50 51# ウィンドウを動かす 52win.mainloop() 53

ifの後ろにある、cが定義されていないとの事で、def関数の中にあるcが受け渡せていないのだと思います
def関数の位置が悪いのかなと思い、

python

1def ok_click(): 2 while True : 3 label1["text"]=q[n] 4 a=random.randint(0,100) 5 label2["text"]=a 6 c= int(text1.get()) 7 8 if a != c: 9 continue 10 else: 11 n=(n+1)% g

とすると、エディタ上でcontinueが赤くハイライトされ、SyntaxError「'continue'not properly in loop」が表示されます

●ご教授頂きたいこと
➀、冒頭のShellで実行できるコードを、tkinterで実行できるコード
➁、tkinter内でOKボタンをクリックする以外にも、キーボードの「Enter」ボタンで次の質問に進めるコード
➂、text内に半透明で「ここに数字を入力してください」とデフォルト表示されており、クリックすると消えるコード

欲張ってすみません、どれか一つだけでも結構です
よろしくお願いいたします

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

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

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

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

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

guest

回答2

0

ベストアンサー

クリック1回分の処理をする関数を定義して、呼び出すようにしないといけないです。
もろもろ対応してみました。

python

1import tkinter as tk 2import random 3 4# ウィンドウを作成 5win = tk.Tk() 6win.title("質問") 7win.geometry("500x250") 8 9# 部品用変数を用意 10question = tk.StringVar() 11value = tk.StringVar() 12entry = tk.StringVar() 13 14# 質問 15q = ["Aでいいですか?", "Bでもいいですか?", "Cでもいいですよね?"] 16q.append("Dも追加していいですか?") 17 18# 処理定義 19n = 0 20question.set(q[n]) 21value.set(random.randint(0, 100)) 22 23def ok_click(event=None): 24 if entry.get() == value.get(): 25 global n 26 n = (n + 1) % len(q) 27 question.set(q[n]) 28 entry.set("") 29 value.set(random.randint(0, 100)) 30 31# 部品を作成 32tk.Label(win, textvariable=question).pack() 33tk.Label(win, textvariable=value).pack() 34tk.Label(win, text="OKなら同じ数字を入力してokを押してください").pack() 35text = tk.Entry(win, textvariable=entry) 36text.bind('<Return>', ok_click) 37text.pack() 38tk.Button(win, text='ok', command=ok_click).pack() 39 40# ウィンドウイベント処理開始 41win.mainloop()

投稿2020/05/06 05:33

編集2020/05/06 05:40
shiracamus

総合スコア5406

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

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

swing

2020/05/06 06:59

早々にご回答ありがとうございます 書いて頂いたコードをコピペして実行すると、作りたかったGUIを得れました ありがとうございます そして、すごくシンプルで美しいコードですね 必要最低限で書いてあるのでしょうね 初めて見たキーワードもあり、これから1行づつコピペしてどのコードがどの仕事をしているのかを勉強致します ありがとうございました
guest

0

(1) (2) のみの回答です。

while ループを廃止し、以下のようにします。

python

1def next_question(): 2 global a 3 label1["text"] = q[n] 4 label2["text"] = a = random.randint(0,100) 5 text1.delete(0, tk.END) 6 7def ok_click(event=None): 8 global c, n 9 c = int(text1.get()) 10 if a != c: 11 win.destroy() 12 else: 13 n = (n+1) % g 14 next_question() 15 16next_question() 17 18text1.bind("<Return>", ok_click)

コンソールのプログラムにGUIを導入するにあたり、
「イベント駆動」という事を意識する必要があります。

通常のプログラムであれば、プログラムは上から下へ流れるように実行されますが、
Tkinter 等のGUIを使ったプログラムでは、
メインのループはマウスのイベントや描画を更新する処理(mainloop)になる為、
メインスレッドでは他のメインループを持つことはできません。
(描画や入力等の操作が出来なくなりウィンドウが固まります)

GUIプログラミングで、どのようにプログラムを構成するかというと、
入力があった時、ボタンが押された時等をトリガーに、
何かイベントが起きた時に呼ばれる関数を登録 (この場合 ok_click) しておき、
そこでイベントが起こった場合の処理、入力がの判定や次の質問へ進む処理を行います。


キーボードの「Enter」ボタンで次の質問に進めるコード

text1.bind("<Return>", ok_click)

Enter キーが押された時に、ok_click関数が呼ばれるように登録。

※ "<Enter>" ではありません。<Enter> もありますが、
カーソルが入った時・離れた時のイベントに<Enter>, <Leave>が使われてます。

bindで登録した場合、関数にはイベントオブジェクトが渡されるので、
引数が異なります。

ok_click() # <-- ボタンが押された時 ok_click(event) # <-- Enter キーが押された時

引数なしの呼び出し両方に対応する為、デフォルト引数を設定してます。(変更点)

def ok_click(event=None): ...

(3) に関しては、Tkinter のEnter 標準の機能にはないので、
自分で実装するかコードを借用する必要があります。

「Placeholder」 で検索すると幾つかサンプルコードが見つかります。

イメージ説明

投稿2020/05/06 05:08

teamikl

総合スコア8760

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

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

swing

2020/05/06 06:50

早々にご回答ありがとうございます Sellで動きさえすれば、GUIで表現するのは、割り当てるぐらいに考えていたのですが、 書き方も変わってしまうのですね ご指摘頂いておりますように、何度もウィンドウが固まりました (自分で書いたモノがちゃんとフリーズするというちょっとした感動がありましたが。。) ご教授頂いた内容ですと、GUIにて作成する際はwhile文は使えなく、トリガー→処理を意識して書くのですね。➁、③も回答頂き、ありがとうございます。「Placeholder」実装できるようにします。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問