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

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

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

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

Python

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

Q&A

解決済

2回答

5016閲覧

Python tkinterでボタンを押したときにラジオボタンで選択されている内容を取得したい

per_

総合スコア41

Tkinter

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

Python

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

0グッド

0クリップ

投稿2020/02/05 11:41

前提・実現したいこと

プログラムの条件分岐の中で、
変数hogeが空白のときに tkinter のラジオボタンを用いてユーザー入力をする
という処理をさせたいと考えています。
イメージ説明

該当のソースコード

Python

1#!python3.7 2# -*- coding: utf-8 -*- 3import tkinter as tk 4 5def hoge_input(): 6 root = tk.Tk() 7 root.option_add('*font', ('FixedSys', 14)) 8 root.title('えらぶ') 9 selection = ['選択肢A','選択肢B','選択肢C'] 10 rdo_var = tk.IntVar() 11 12 for i in range(len(selection)): 13 tk.Radiobutton(root, value=i, variable=rdo_var, text=selection[i]).pack(anchor = tk.CENTER,padx=30,pady=3) 14 15 def btn_click(): 16 num = rdo_var.get() 17 hoge = selection[num] 18 root.destroy() 19 print(hoge) 20 return hoge 21 22 btn = tk.Button(root, text='OK', command=btn_click) 23 btn.pack(fill ='x',padx=40,pady=3) 24 root.mainloop() 25 26 27if __name__ == "__main__": 28 # hogeを格納する関数hoge_search()→hogeに該当する値が無かった場合にユーザー選択 29 # hoge_search() 30 31 if hoge == '': 32 hoge_input() 33 34 # ここでユーザーが選択した選択肢A/B/Cを表示させたい 35 print(hoge) 36 # None

わかっていること

btn_clickのイベントのタイミングで変数を格納したいのですが、
returnしてもtk.Button(root, text='OK', command=btn_click)ここに値が戻ってしまう形になってしまい
main関数のhogeへの値の渡し方がわかりません。

def btn_click(): num = rdo_var.get() hoge = selection[num] root.destroy() print(hoge)  #この時点ではhogeが格納されている return hoge  #returnされない

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

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

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

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

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

guest

回答2

0

ベストアンサー

基本的には shiracamusさんが回答されているように hoge_input関数の戻り値として選択されている値を渡すと良いかと思います が、気になる点を2点ほど

(1)
最終的に得たい値が "選択肢のIndex" ではなく "選択肢の内容" なのでしたら、tk.IntVar() ではなくて tk.StringVar() を使うほうが適当ではないでしょうか。
こうすることで Radiobutton生成部のループも

Python

1 for s in selection: 2 tk.Radiobutton(root, value=s, variable=rdo_var, text=s).pack(anchor = tk.CENTER,padx=30,pady=3)

と少しスッキリ書けます

(2)
ラジオボックスが選択されている状態でウインドウ上部の "閉じる(X)ボタン"を押されたときの挙動ですが、

  • 選択されていないと見なす
  • 現在選択されている値を返す

によって記述が異なります。後者の場合はshiracamusさんが書かれているようにhoge_input関数の最後に

Python

1def hoge_input(): 2 # (略) 3 return rdo_var.get()

とすると良いのですが、前者の場合は質問のコードのようにbtn_click関数を作成してその中で一度**"hoge_input関数のローカ ル変数"**に格納した後に、その変数を戻り値として返すようにするかと良いと思います。

以上を修正すると以下のようになります。

Python

1import tkinter as tk 2 3def hoge_input(): 4 root = tk.Tk() 5 root.option_add('*font', ('FixedSys', 14)) 6 root.title('えらぶ') 7 selection = ['選択肢A','選択肢B','選択肢C'] 8 result = 'NotSelected' # 選択されていないときに返す値を入れておく 9 rdo_var = tk.StringVar(value=result) 10 11 for s in selection: 12 rb = tk.Radiobutton(root, value=s, variable=rdo_var, text=s) 13 rb.pack(anchor = tk.CENTER,padx=30,pady=3) 14 15 def btn_click(): 16 nonlocal result # 親関数の変数に書き込むのでこれが必要 17 result = rdo_var.get() 18 root.destroy() 19 20 btn = tk.Button(root, text='OK', command=btn_click) 21 btn.pack(fill ='x',padx=40,pady=3) 22 root.mainloop() 23 return result # 最終的にこの変数に書き込まれている内容を返す 24 25 26if __name__ == "__main__": 27 hoge = '' # とりあえずコードを動作させるために追記 28 29 if hoge == '': 30 hoge = hoge_input() 31 32 # ここでユーザーが選択した選択肢A/B/Cを表示させたい 33 print(hoge)

投稿2020/02/06 00:21

magichan

総合スコア15898

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

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

shiracamus

2020/02/06 00:26 編集

選択されていない値には、Noneを使うといいですね。 ただ、値が無いときにこの処理を呼び出しているので、再びこの処理を呼び出すことになりそうな予感。
magichan

2020/02/06 01:00 編集

それは少し考えたのですが、元々 hoge には'空文字'が入っていますので、それを None に戻すのは逆に???な気がします。(受け側に処理を追加するとよいだけなのですが) まあこの後の処理次第なのですが、Str型を前提としている処理が書かれているかもしれないので空文字のままのほうが適当かもしれないとも思いましたが、とりあえずサンプルとして違う文字列に変えております。 この辺は明確な仕様が提示されている訳ではないので、質問者さんが決定して必要に応じて変更するとよいのではないでしょうか。
shiracamus

2020/02/06 01:20 編集

'NotSelected'やNoneや空文字が返ってきたら、結局再びこの関数を呼び出すことになるのではないかと思った次第です。 それならば、選択項目の先頭をデフォルト値にしておけば、X でウィンドウを閉じてもデフォルト値が帰るので問題ないかと考えました。IntVar はデフォルトで 0 になりますので。 Xでウィンドウを閉じたときにどうしたいのか、質問者に確認しない限り、どうするのが最善かわからないですね。
per_

2020/02/06 02:22 編集

> (1)tk.IntVar() ではなくて tk.StringVar() を使うほうが適当 まさしくこの通りで、この後の処理では文字列そのものを処理するため、たいへん助かりました。 > (2)"閉じる(X)ボタン"を押されたときの挙動 ここの部分を質問に記載しておらず恐縮ですが、今回は”選択されていないと見なす”こととしたかったため、 magichanさんのこの回答をベストアンサーとさせていただきます。 `nonlocal result` 目から鱗でした。もっと勉強します。 ご指摘いただいた箇所を書き直したところ、要求していた動作が実現できました。たいへんありがとうございました。
guest

0

これでいかがですか?
なお、Python3では coding:utf-8 指定不要です。

python

1#!python3.7 2import tkinter as tk 3 4 5def hoge_input(): 6 root = tk.Tk() 7 root.option_add('*font', ('FixedSys', 14)) 8 root.title('えらぶ') 9 selections = '選択肢A', '選択肢B', '選択肢C' 10 rdo_var = tk.IntVar() 11 12 for i, selection in enumerate(selections): 13 tk.Radiobutton(root, value=i, variable=rdo_var, text=selection).pack(anchor=tk.CENTER, padx=30, pady=3) 14 15 btn = tk.Button(root, text='OK', command=root.destroy) 16 btn.pack(fill='x', padx=40, pady=3) 17 root.mainloop() 18 return selections[rdo_var.get()] 19 20 21if __name__ == "__main__": 22 # hogeを格納する関数hoge_search()→hogeに該当する値が無かった場合にユーザー選 2324 hoge = '' 25 # hoge_search() 26 27 if hoge == '': 28 hoge = hoge_input() 29 30 # ここでユーザーが選択した選択肢A/B/Cを表示させたい 31 print(hoge)

投稿2020/02/05 12:48

編集2020/02/06 01:07
shiracamus

総合スコア5406

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

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

per_

2020/02/06 02:28

shiracamusさんご回答ありがとうございました!ばっちり動作なうえ、とてもすっきりとしたコードを記載いただきました。 特に `for i, selection in enumerate(selections):` ここと同じようなことを別の箇所で(ぐちゃぐちゃなコードで)書いていたためとても改善できました。 ×ボタン挙動のことがあり別の回答をベストアンサーとさせていただきましたが、とても勉強になりました。 > なお、Python3では coding:utf-8 指定不要です。 Python2系での記載事項だったことを知りました…ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問