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

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

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

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

Python

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

Q&A

解決済

1回答

1487閲覧

TkInter ラジオボタンのグループ単位での、単一選択制御ができない。

saya24

総合スコア222

Tkinter

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

Python

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

0グッド

0クリップ

投稿2020/06/05 07:54

標題の件、ラジオボタンのグループ管理は variableの設定を 同じ変数を指定することでなされるのではないのでしょうか?
初期値をこちらの記事を参考に対処したつもりですが、
・初期値の設定選択が活きていない
・グループ単位で 単一選択の制御ができない
・クリックではなく、マウスオーバのみで選択になってしまうことがある
問題が生じています。

本来 二つのグループのラジオボタンなので、双方YesもしくはNoのいづれかが選択されているべきなのですが、ご覧の有様です。
どういう対策を投じればよいのでしょうか?
絵

Python

1from tkinter import * 2import tkinter.ttk as ttk 3import tkinter.scrolledtext as tksc 4import math 5 6class Apprication(ttk.Frame): 7 8 def __init__(self, app): 9 super().__init__(app) 10 self.pack(fill=BOTH, expand=True) 11 12 btn1 = ttk.Button(self, text="Sub", command=self.openDialog) 13 btn1.bind('<Return>', self.openDialog) 14 btn1.pack(fill=BOTH, expand=True) 15 btn1.focus_set() 16 17 btn2 = ttk.Button(self, text="Quit", command=app.quit) 18 btn2.bind('<Return>', lambda _: app.quit()) 19 btn2.pack(fill=BOTH, expand=True) 20 21 self.menu() 22 23 24 25 def menu(self): 26 menu_top = Menu(app) 27 menu_file = Menu(menu_top, tearoff=False) 28 menu_open = Menu(menu_top, tearoff=False) 29 30 app.configure(menu=menu_top, bg="#F0FFFF") 31 32 menu_top.add_cascade (label='File(F)', menu=menu_file, underline=0) 33 34 menu_file.add_cascade(label='Open(O)', underline=0, menu=menu_open) 35 menu_open.add_command(label='Sub(S)', underline=0, command=self.openDialog) 36 menu_file.add_command(label='Quit(Q)',underline=0, command=app.quit) 37 38 39 40 41 42 # 子画面開く 43 def openDialog(self, event=None): 44 45 self.dialog = Toplevel(self) 46 self.dialog.title("Sub Menu") 47 48 #フォームサイズを実行端末から導き、ド真中に配置表示 49 lw = math.ceil(ww * 0.408) 50 lh = math.ceil(wh * 0.477) 51 self.dialog.geometry(str(lw)+"x"+str(lh)+"+"+str(int(ww/2-lw/2))+"+"+str(int(wh/2-lh/2)) ) 52 53 self.dialog.configure(bg="#F0FFFF") 54 self.dialog.resizable(0,0) 55 self.dialog.protocol('WM_DELETE_WINDOW', (lambda: 'pass')()) 56 57 58 # modalに 59 self.dialog.grab_set() 60 61 lbfrm1 = LabelFrame(self.dialog, text="Detail setting") 62 lbfrm1.grid(padx=(10,10)) 63 radioValue1 = IntVar() 64 rd1 = Radiobutton(lbfrm1, text="Yes", bg="#F0FFFF", variable=radioValue1, value=1, activebackground="#F0FFFF") 65 rd1.grid(row=1, column=0) 66 radioValue1.set(1) 67 rd2 = Radiobutton(lbfrm1, text="No", bg="#F0FFFF", variable=radioValue1, value=2, activebackground="#F0FFFF") 68 rd2.grid(row=1, column=1) 69 radioValue2 = IntVar() 70 rd3 = Radiobutton(lbfrm1, text="Yes", bg="#F0FFFF", variable=radioValue2, value=1, activebackground="#F0FFFF") 71 rd3.grid(row=1, column=3) 72 radioValue2.set(1) 73 rd4 = Radiobutton(lbfrm1, text="No", bg="#F0FFFF", variable=radioValue2, value=2, activebackground="#F0FFFF") 74 rd4.grid(row=1, column=4) 75 76 77 # 閉じるボタン 78 btn3 = Button(self.dialog, text='Quit', command=self.closeDialog, width=10, takefocus=1) 79 btn3.grid(row=5, column=10, pady=10, padx=(0,10)) 80 81 82 self.dialog.grid_rowconfigure(1, weight=1) 83 self.dialog.grid_rowconfigure(3, weight=1) 84 self.dialog.grid_columnconfigure(2, weight=1) 85 86 87 88 # 子画面閉じる 89 def closeDialog(self): 90 self.dialog.destroy() 91 92 93 94if __name__ == '__main__': 95 96 #世間でいうrootをappとしています 97 app = Tk() 98 99 #実行端末の画面サイズを取得 100 ww = app.winfo_screenwidth() 101 wh = app.winfo_screenheight() 102 103 app.update_idletasks() 104 105 #フォームサイズを実行端末から導き、ド真中に配置表示 106 lw = math.ceil(ww * 0.208) 107 lh = math.ceil(wh * 0.277) 108 app.geometry(str(lw)+"x"+str(lh)+"+"+str(int(ww/2-lw/2))+"+"+str(int(wh/2-lh/2)) ) 109 110 #タイトルを指定 111 app.title("Main Menu") 112 113 #フォームの最大化、×ボタン操作を無効化 114 app.resizable(0,0) 115 app.protocol('WM_DELETE_WINDOW', (lambda: 'pass')()) 116 117 118 119 menu_top = Menu(app) 120 menu_file = Menu(menu_top, tearoff=False) 121 menu_open = Menu(menu_top, tearoff=False) 122 123 app.configure(menu=menu_top, bg="#F0FFFF") 124 125 menu_top.add_cascade (label='File(F)', menu=menu_file, underline=0) 126 127 menu_file.add_cascade(label='Open(O)', underline=0, menu=menu_open) 128 menu_open.add_command(label='Sub(S)', underline=0, command="app.openDialog") 129 menu_file.add_command(label='Quit(Q)',underline=0, command=app.quit) 130 131 132 # フレームを作成する 133 frame = Apprication(app) 134 # 格納したTkインスタンスのmainloopで画面を起こす 135 app.mainloop()

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

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

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

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

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

guest

回答1

0

ベストアンサー

radioValue1 radioValue2それぞれにself.としてあげれば解消される様です。

参考URL

投稿2020/06/05 08:43

nto

総合スコア1438

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

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

teamikl

2020/06/05 09:17

ローカル変数をインスタンス変数に変更ですね。同じ方法で修正を確認出来ました。 何故マウスオーバーで選択になるのかはうまく説明できませんが、 原因は、Variable系のオブジェクトは、デストラクタで破棄される為で、 ローカル変数である、radioValue1, radioValue2 では関数が終わった時にはなくなり、 初期値が設定されるタイミングでは参照できなくなってしまいます。 ボタン等のウィジェット類はデストラクトが無くtk側で管理されるので大丈夫ですが、 tkinter では他に PhotoImage も同様の注意が必要です。
nto

2020/06/05 10:05

関数の処理が終わったタイミングで変数が破棄されるけども その変数が使用されたオブジェクトが残ってしまっている為に生じてしまう 純粋に予期しない想定外のエラーという事なのでしょうかね?
teamikl

2020/06/05 11:06 編集

IntVarが利用したリソースはデストラクタで削除されるので残りはしてません。 なくなってしまった為に起こっている挙動だと思います。 Radiobutton(..., variable=radioValue1) と引数に渡してますが、 Python側ではtk側でのIDとなる文字列を残すのみで、 pythonのIntVarオブジェクト自身の参照は残しません。->ローカル変数がGCに回収されてしまう原因 ラジオボタンの初期化は、openDialog関数が終わった後 mainloop に処理が戻った時ですが、 radioValue1 は openDialog関数が終わった時には破棄されていて、 ラジオボタンが生成される時には無くなっている。→ 初期値が表示されない原因
saya24

2020/06/05 11:45

ntoさん、teamiklさん お陰様で無事問題解決できました、ありがとうございます。。インスタンス変数にする必要があったのですね。初歩的なことでお時間を頂きすみません。 気がついたら以前自分が利用したコンボボックスやチェックボックスの際は インスタンス変数にして選択結果を得ておりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問