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

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

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

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

Tkinter

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

Q&A

解決済

1回答

978閲覧

tkinterのラジオボタンの選択が反映されません

negi212

総合スコア1

Python 3.x

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

Tkinter

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

0グッド

0クリップ

投稿2023/03/26 13:46

編集2023/03/26 13:59

実現したいこと・発生している問題

pythonのtkinterでguiアプリを作っています。過去のデータをshelveに保存して、ラジオボタンで選択して読み込もうとしているのですが、2番目の値を選択したのに1番目の値が出力されてしまいます。

該当のソースコード

python

1import shelve 2import tkinter as tk 3 4path="C:\\Users\\XXXXX\\Documents\\python\\" 5 6def history(): 7 item = [] 8 with shelve.open(path+'history') as db: 9 for key in db.keys(): 10 item.append(f"{key}") 11 root3=tk.Tk() 12 root3.title("履歴の復元") 13 val = tk.IntVar() 14 val.set(0) 15 rb_list=[] 16 for i in range(len(item)): 17 rb=tk.Radiobutton(root3,value = i,variable =val,text = item[i],font=("",15)) 18 rb_list.append(rb) 19 rb_list[i].pack(anchor=tk.W) 20 def choice(): 21 ch = val.get() 22 print(item[ch]) 23 button = tk.Button(root3,text = '読み込む',command = choice,font=("",15)).pack() 24 root3.mainloop() 25 26root=tk.Tk() 27button_=tk.Button(root,text="履歴",command=history) 28button_.pack() 29root.mainloop()

試したこと

以下のコードだと上手くいきました。

python

1import shelve 2import tkinter as tk 3 4path="C:\\Users\\XXXXX\\Documents\\python\\" 5 6def history(): 7 item = [] 8 with shelve.open(path+'history') as db: 9 for key in db.keys(): 10 item.append(f"{key}") 11 root3=tk.Tk() 12 root3.title("履歴の復元") 13 val = tk.IntVar() 14 val.set(0) 15 rb_list=[] 16 for i in range(len(item)): 17 rb=tk.Radiobutton(root3,value = i,variable =val,text = item[i],font=("",15)) 18 rb_list.append(rb) 19 rb_list[i].pack(anchor=tk.W) 20 def choice(): 21 ch = val.get() 22 print(item[ch]) 23 button = tk.Button(root3,text = '読み込む',command = choice,font=("",15)).pack() 24 root3.mainloop() 25history()

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

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

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

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

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

guest

回答1

0

ベストアンサー

root = tk.Tk() と root.mainloop() は、プログラム中で1か所になるようにコードを構成しましょう。

tk.Tk() は、ウィンドウを生成する他に、ライブラリの初期化処理も含むので、
2度以上呼び出す場合は注意が必要になります。
もし2つ以上のウィンドウが必要な場合は tk.Tk の代わりに tk.Toplevel を用います。

また、現状のコードでは問題になっていませんが、tkinter の非ウィジェットのオブジェクト
IntVar を格納する変数は、ローカル変数の場合、関数を抜けてしまうと破棄される点に注意。
対策として、何処か外側のスコープの変数に格納するようにします。

投稿2023/03/28 10:12

編集2023/03/28 10:16
teamikl

総合スコア8664

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

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

negi212

2023/03/30 02:54

ありがとうございます。 いろいろ試してみたところ、val=tk.IntVar()をval=tk.IntVar(root3)に変更したら上手くいきました。 指摘していただいたことも今後注意しようと思います。
teamikl

2023/03/30 07:12 編集

> val=tk.IntVar()をval=tk.IntVar(root3)に変更したら上手くいきました。 IntVar に親を指定する解決策は、変数のスコープとは別問題で、 本質的な解決にはなっておらず、別の問題が残る可能性があります。 tkinter ライブラリは、Tk() 呼び出し時に初期化が行われ tk.IntVar() と省略した時の暗黙の親(root)を設定します。 しかし、root3 = tk.Tk() で作ったウィンドウでは、この親指定を省略したときの親が 意図した root とは別のものになります。 この挙動は、事前に tk.NoDefaultRoot() を呼び出すことにより、 親指定を強制的に省略できなくしますが(省略時エラーになる) Tk() を複数回呼び出さないようにする解決方法をお勧めします。 具体的には、 root3 = tk.Tk() ではなく root3 = tk.Toplevel() を用いる。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問