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

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

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

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

Python

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

Q&A

解決済

1回答

1882閲覧

チェックボックスが全部選択されてしまう

yep

総合スコア45

Tkinter

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

Python

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

0グッド

0クリップ

投稿2019/04/24 16:28

編集2019/04/26 17:05

csvのcolumnsを動的に取得できたら便利だなと思い書いたのですが、
チェックボタンの選択で一個、一個が独立してチェックできるのではなく
一回押したら全部の欄にチェックがついていしまい困っています。

python

1import os,sys 2from tkinter import * 3import tkinter 4from tkinter import filedialog 5from fir_win import sub_window3 6import codecs 7import pandas as pd 8 9def func(): 10 sub_window3.func() 11 12 13def file_search(): 14 root = tkinter.Tk() 15 root.withdraw() 16 fTyp = [("","*.csv")] 17 iDir = os.path.abspath(os.path.dirname(__file__)) 18 filepath = filedialog.askopenfilename(filetypes = fTyp,initialdir = iDir) 19 sub_win = Toplevel() 20 with codecs.open(filepath, "r", "cp932", "ignore") as file: 21 df = pd.read_table(file, delimiter=",", skipinitialspace=True) 22 columns = df.columns.values 23 col_var = tkinter.IntVar() 24 for i in range(len(columns)): 25 col = tkinter.Checkbutton(sub_win, variable=col_var, text=columns[i])<--全部チェックがついてしまいます。 26 col.place(x=50, y=30 + (i * 24)) 27 num = col_var.get() 28 label0 = tkinter.Label(sub_win,text=u'Data cleaning[.csv]') 29 label0.place(x=5, y=5) 30 sub_win.geometry("385x400") 31 button2 = tkinter.Button(sub_win, text='Start!', command=func) 32 button2.place(x=5, y=250)

もしご存知の方がいらっしゃれば、ご教授頂きたく存じます。

python

1def do_something(): 2 sub_win = Toplevel() 3 col_var = tkinter.IntVar() 4 if col_vars[0].get(): 5 col_var = [] 6 for i, cn in enumerate(columns): 7 col_var = tkinter.IntVar() 8 col_vars.append(col_var) 9 col = tkinter.Checkbutton(sub_win, variable=col_var, text=cn) 10 col.place(x=50, y=30 + (i * 24)) 11 if col_vars[1].get():#繰り返し

KSwordOfHasteさんに教えていただいた情報を基に作成したインスタント部分です。
col_vars.append(col_var)
の部分でName is not definedになってしまいます。

追記:

python

1from tkinter import * 2import tkinter.ttk as ttk 3import tkinter 4import tkinter.filedialog as filedialog 5import pandas as pd 6import os,codecs 7 8class FiledialogApp(ttk.Frame): 9 10 def __init__(self, app): 11 super().__init__(app) 12 self.pack() 13 14 self.filename = StringVar() 15 16 label = ttk.Label(self,text="File>>") 17 label.pack(side="left") 18 filenameEntry = ttk.Entry(self,text="",textvariable= self.filename) 19 filenameEntry.pack(side="left") 20 21 button = ttk.Button(self,text="Select",command = self.openFileDialog) 22 button.pack(side="left") 23 24 button_c = ttk.Button(self, text="Close",command = quit) 25 button_c.pack(side="left") 26 27 def openFileDialog(self): 28 # ファイルダイアログにより処理対象のファイルパスを選ばせる 29 filepath = filedialog.askopenfilename(filetypes=[(".csv","*.csv")]); 30 self.filename.set(filepath) 31 # ファイルを読み込む 32 with codecs.open(filepath, "r", "cp932", "ignore") as file: 33 df = pd.read_table(file, delimiter=",", skipinitialspace=True) 34 columns = df.columns.values 35 # データフレーム上の列数分だけ Checkbotton を生成すると仮定 36 col_vars = [] 37 for i, column in enumerate(columns): 38 col_var = tkinter.IntVar() 39 col_vars.append(col_var) 40 cb = ttk.Checkbutton(variable=col_var, text=column) 41 cb.place(x=50, y=30 + (i * 24)) 42 43 # ボタンのハンドラー関数 44 def on_start_button(): 45 for i, column in enumerate(columns): 46 checked = 'checked' if col_vars[i].get() else 'is not checked' 47 print(f"{column} column {checked}") 48 # 必要に応じて何かする 49 50 button_1 = ttk.Button(text='Start!', command=on_start_button) 51 button_1.place(x=5, y=250) 52 53 54 55if __name__ == '__main__': 56 app = Tk() 57 app.geometry("400x300") 58 app.title("Select your file[.csv]") 59 frame = FiledialogApp(app) 60 app.mainloop()

教えていただいたコードでgui画面を作ってみました。
正常に動きました。

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

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

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

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

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

guest

回答1

0

ベストアンサー

同一のIntVarインスタンスを全てのCheckbuttonで共有しているのが問題の原因です。個々のCheckbuttonそれぞれに別々のIntValueインスタンスを指定してください。またチェックボタンを配置したばかりで利用者がボタンを操作してもいない時点で
num = col_var.get()
とするのは意味がないと思います。チェックボタンの状態が必要になる時点で参照してください。

python

1import tkinter as tk 2 3... 4 5def file_search(): 6 ... 7 8 def do_something(): 9 if col_vars[0].get(): 10 # 最初のCheckbuttonがチェックされていた 11 ... 12 if col_vars[1].get() 13 # 2番目のCheckbuttonがチェックされていた 14 ... 15 # 等々 16 17 run_button = tk.Button(sub_win, text="run", 18 command=do_something) 19 ... 20 21 col_vars = [] 22 for i, cn in enumerate(columns): 23 col_var = tk.IntVar() 24 col_vars.append(col_var) 25 col = tk.Checkbutton(sub_win, variable=col_var, text=cn) 26 col.place(x=50, y=30 + (i * 24)) 27 ...

追記:

質問文にコードを追記していただいたのですが・・・自分の回答は質問者さんによく伝わらなかったようです。また、ボタンを押したときに呼び出されるハンドラー関数からどの範囲の変数が見えるか、ファイルダイアログを開いたりDataFrameをロードしたり、GUIの初期化をしたりといったもろもろの制御の流れをどう記述したらよいか等々についてはっきりとイメージできていないような印象でしたので、「何が問題でどうしたらよいか」という説明をするかわりに、単純な例を書いてみることにしました。下記を動かし動作を確認した上で個々のコードがどういうふうに動くのかを考えてみてはいかがでしょう?

スミマセンが、自分が不自然に感じた細々とした点は断りなしに変更させていただいています。

Python

1import os 2import tkinter as tk 3import tkinter.filedialog 4import codecs 5import pandas as pd 6 7 8def main(): 9 root = tk.Tk() 10 root.withdraw() 11 12 # ファイルダイアログにより処理対象のファイルパスを選ばせる 13 14 filetypes = [("", "*.csv")] 15 initialdir = os.path.abspath(os.path.dirname(__file__)) 16 filepath = tk.filedialog.askopenfilename(filetypes=filetypes,initialdir=initialdir) 17 18 # ファイルを読み込む 19 with codecs.open(filepath, "r", "cp932", "ignore") as file: 20 df = pd.read_table(file, delimiter=",", skipinitialspace=True) 21 columns = df.columns.values 22 23 # ウィンドウの初期化 24 sub_win = tk.Toplevel() 25 sub_win.geometry("385x400") 26 27 # データフレーム上の列数分だけ Checkbotton を生成すると仮定 28 col_vars = [] 29 for i, column in enumerate(columns): 30 col_var = tk.IntVar() 31 col_vars.append(col_var) 32 cb = tk.Checkbutton(sub_win, variable=col_var, text=column) 33 cb.place(x=50, y=30 + (i * 24)) 34 label0 = tk.Label(sub_win, text=u'Data cleaning[.csv]') 35 label0.place(x=5, y=5) 36 37 # ボタンのハンドラー関数 38 def on_start_button(): 39 for i, column in enumerate(columns): 40 checked = 'checked' if col_vars[i].get() else 'is not checked' 41 print(f"{column} column {checked}") 42 # 必要に応じて何かする 43 44 button2 = tk.Button(sub_win, text='Start!', command=on_start_button) 45 button2.place(x=5, y=250) 46 root.mainloop() 47 48 49if __name__ == '__main__': 50 main()

もう少し追記:

最初の回答に書いたdo_somethingという関数名はわかりにくかったようなのでon_start_buttonという関数名に変えました。この関数の定義場所に注意してください。注意すべきはon_start_button関数を

(A)main関数の中で定義すること
(B)button2の生成より前に定義すること

です。(A)の理由はmain関数のローカル変数col_varsをon_start_buttonからアクセスするため。(B)の理由はButton生成のcommand引数には「その時点で関数が定義済みでないといけないから」です。

投稿2019/04/24 17:40

編集2019/04/26 16:21
KSwordOfHaste

総合スコア18394

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

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

yep

2019/04/25 08:53 編集

すみません。教えて頂いて恐縮なのですが、難しかったです。 def do_something(): sub_win = Toplevel() col_var = tkinter.IntVar() if col_vars[0].get(): col_var = [] for i, cn in enumerate(columns): col_var = tkinter.IntVar() col_vars = append(col_var) col = tkinter.Checkbutton(sub_win, variable=col_var, text=cn) col.place(x=50, y=30 + (i * 24)) if col_vars[1].get(): col_vars.append(col_var)では、動きませんでした。
KSwordOfHaste

2019/04/25 11:06 編集

コメント欄にコードを書くのは止した方がよいです。特にインデントが重要なPythonの場合はそうです。質問は編集できますので、そちらに書き込んだ方がよいでしょう。しかし元のコードを書き替えると他の閲覧者の方に「そもそもどういうコードに対しての質問だったか」がわからなくなるので質問コードは書き換えるのではなく新たに追記する方がよいです。あまり質問文が長くなると質問内容が閲覧者にフォローしずらくなるので感心しませんが、上記の程度の修正を元のコードに反映したものを追記するぐらいなら大丈夫だと思います。
yep

2019/04/26 13:24

すみません。直してみましたが分かりませんでした。
KSwordOfHaste

2019/04/26 15:13

do_something関数だけ書いても質問者さんが自分の回答を咀嚼できているかどうか確認できません。多分咀嚼できていないような印象ですがはっきりしません。またfir_winモジュールなど「閲覧者に中身がわからないコードを前提としたプログラム」を提示するのは控えてください。問題の本質に無関係なところは削除し、提示したコードだけで動作する「完全なプログラム」を提示しましょう。そうするためには元のコードをより短い単純なものに変更する必要があります。質問者さんにとって面倒かも知れませんが、そういう配慮が「質問側へ確実にコードの意図を伝える」コツです。
KSwordOfHaste

2019/04/26 16:11

とはいってみたものの、逆にコード例を私の方から提示してみることにしました。回答への追記部分のコードをご覧ください。こういう感じの「コピペすればそのまま試すことができる、完全なコード」を質問文に書いてほしかったのです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問