機械系エンジニアの備忘録

20代独身社会人。仕事では機械・機構の研究開発を行っているエンジニアが、自分の専門分野ではないpythonを扱って楽しむブログです。

MENU

【Part6】python3-tkinterの使い方 - チェックボタンを使おう(2/3)

【Part6】チェックボタンの状態によって異なる処理を行う.

1.前回のおさらい

前回は必要な部品(ラベル,チャックボタン×5,ボタン)を作りました。

コードは以下になります。

import tkinter as tk #tkinterの読み込み

#ウインド(win)を作成
win=tk.Tk()
win.title("Hello world")
win.geometry("500x300") #ウインドの大きさを200×300に設定

#ラベルの作成
label=tk.Label(text="終了したタスクをチェックしてください")
label.place(x=10,y=5)

#チェックボックス(変数名:Check)の作成
Check_number=5
Check_val=tk.BooleanVar()
Check_val.set(True)
for i in range(Check_number):
    Check=tk.Checkbutton(text="チェックボタン",variable=Check_val)
    Check.place(x=10,y=30*i+30)

#ボタンの作成
Button=tk.Button(width=5,text="評価",background="#FFFFFF")
Button.place(x=30,y=250)

#ウインドの表示
win.mainloop()

f:id:stjun:20190519000107j:plain

 

今回はチェックボックスにチェックがついているかを確認し,ついていたら処理Aを,ついていなければ処理Bを,といった感じにチェックの状態で処理を変える機能を作っていきます. 

2.完成コード

前回にも載っていますが,改めて載せておきます。

import tkinter as tk

#ウインド画面の設定
win=tk.Tk()
win.title("python3_tkinter_part5")
win.geometry("500x300")

#ラベル(変数名:label)の作成
label=tk.Label(text="終わったタスクにチェックを入れて評価ボタンを押してください")
label.place(x=30,y=5)

#チェックボタン(変数名:Chek_buttn)の作成
Check_list=[]
Check_list_val=[]
Check_buttn_number=5
text_anser=[]
for i in range(Check_buttn_number):
    Check_val=tk.BooleanVar()
    Check_val.set(False)
    Check_buttn=tk.Checkbutton(text="タスク"+str(len(Check_list)+1),variable=Check_val)
    Check_buttn.place(x=30,y=i*30+30)
    Check_list.append(Check_buttn)
    Check_list_val.append(Check_val)

#ボタンを押したらチェックがついてるタスクの数を確認し、チェックの数を表示
    def Click_buttn():
        text_anser=[]
        for i in range(len(Check_list)):
            if Check_list_val[i].get()==True:
                text=tk.Label(text="タスクは終了しました")
                text.place(x=100,y=i*30+32)
                text_anser.append(1)
            else:
                text=tk.Label(text="タスクは未解決です",foreground="red")
                text.place(x=100,y=i*30+32)
        
        if len(text_anser)==Check_buttn_number:
            text=tk.Label(text="お疲れ様でした,今日のタスクは終了です。")
            text.place(x=100,y=250)
        else:
            text=tk.Label(text="終了したタスクは "+str(len(text_anser))+"/"+str(len(Check_list))+"個です")
            text.place(x=100,y=250)
                
#ボタン(変数名:Button)の作成
Button=tk.Button(win,width=5,background="#ffffff",text="評価",command=Click_buttn)
Button.place(x=30,y=250)   
    


#ウインドの表示
win.mainloop()

 

f:id:stjun:20190518231837j:plain

 

f:id:stjun:20190518232429j:plain

 

<説明> 

チェックボックスの状態は以下のコードで取得できます.

変数.get()

例えば,まずチェックボックスを作ります。

import tkinter as tk

#ウインド画面の設定
win=tk.Tk()
win.title("python3_tkinter_part5")
win.geometry("500x300")

Check_val=tk.BooleanVar()
Check_val.set(False)
Check_buttn=tk.Checkbutton(text="タスク",variable=Check_val)
Check_buttn.place(x=30,y=30)

#ウインドの表示
win.mainloop()

f:id:stjun:20190520230730p:plain

ここで

Check_val.get()

を追加するとチェックボタンの有無がTrueかFalseで返ってきます。

例えば以下のように,もしチェックが入ってたらTrueを,入ってなければFalseを返すコードを追加してみます。

import tkinter as tk

#ウインド画面の設定
win=tk.Tk()
win.title("python3_tkinter_part5")
win.geometry("500x300")

#チェックボタンの作成
Check_val=tk.BooleanVar()
Check_val.set(False)
Check_buttn=tk.Checkbutton(text="タスク",variable=Check_val)
Check_buttn.place(x=30,y=30)

#チェックが入ってたらTrueを,入ってなければFalseを返す
if Check_val.get()==True:
print(True)
else:
print(False)

#ウインドの表示
win.mainloop()

今回はチェックが入ってないので以下のようにFalseが返ってきます.

f:id:stjun:20190520231530p:plain

つまり.get()を使えばそれぞれのチェックボックスでのチェックの有無が判別できます。

 

 

次に,5つのチェックボックスをそれぞれ個別に扱う方法を記載します。

どういうことかと言うと,例えば以下のようなコードでチェックボックスを5つ作った時,上から2番目のチェックボックスのチェック有無だけ知りたい場合はどう指定すればよいでしょうか?

import tkinter as tk #tkinterの読み込み

#ウインド(win)を作成
win=tk.Tk()
win.title("Hello world")
win.geometry("500x300") #ウインドの大きさを200×300に設定

#チェックボックス(変数名:Check)の作成
Check_number=5
Check_val=tk.BooleanVar()
Check_val.set(True)
for i in range(Check_number):
Check=tk.Checkbutton(text="チェックボタン",variable=Check_val)
Check.place(x=10,y=30*i+30)

#ウインドの表示
win.mainloop()

f:id:stjun:20190520232053p:plain

結論から言うと,すべて変数Checkとして作ってしまっているため,上から2番目のチェックボックスのチェック有無だけ知ることはできません。またどれか1つのチェックボックスを外そうとすると,全て外れてしまいます。

f:id:stjun:20190520232343p:plain

(一番上のチェックボタンだけクリックしたのに全部外れてしまいました..)

 

解決策としては,リストを新たに作り,for文で作ったチェックボタンをリストに格納していき順番付けをしてあげるという方法があります。

例えば以下の画面とコードを見てください。

 

f:id:stjun:20190520234143p:plain

#チェックボタン(変数名:Chek_buttn)の作成
Check_list=[]
Check_list_val=[]
Check_buttn_number=5
for i in range(Check_buttn_number):
    Check_val=tk.BooleanVar()
    Check_val.set(False)
    Check_buttn=tk.Checkbutton(text="タス    
ク"
+str(len(Check_list)+1),variable=Check_val) Check_buttn.place(x=30,y=i*30+30) Check_list.append(Check_buttn) Check_list_val.append(Check_val)

まず1行目は作ったチェックボタンを格納していくリストを、2行目にはチェックの有無を格納していくリストを空の状態で作っています.

3行目はこれからチェックボックスをいくつ作るかを指定しています。

今回は5個のチェックボックスを作るのでCheck_number=5としています。

4行目for i in range(Check_buttn_number):からfor文でループに入ります。

まず5行目のCheck_val=tk.BooleanVar()と6行目のCheck_val.set(False)は前回の復習になります.

5行目Check_val=tk.BooleanVar()は変数Check_valにTrueかFalseが入るBool型を指定しています。このCheck_valがTrueの時はチェックが付き,Falseの時はチェックが外れます.

6行目Check_val.set(False)ではとりあえずチェックが最初から付いた状態で作成されるようにしています。

そして7行目のCheck_buttn=tk.Checkbutton(text="タスク"+str(len(Check_list)+1),variable=Check_val)でチェックボックスを作成しています。

いまCheck_listは空なのでlen(Check_list)は0になります.そのためstr(len(Check_list)+1)=1になります。すなわちタスク1という名前のチェックボックスをvariable=Check_val=チェック無しで作っています。

8行目ではCheck_buttn.place(x=30,y=i*30+30)で位置をしています.1回目のループではi=0のため1つめのチェックボックスはx=30,y=30の位置に作られることになります。

ここからが重要です。

9行目Check_list.append(Check_buttn)で空であったCheck_listに作ったCheck_buttnを格納し,10行目Check_list_val.append(Check_val)でチェックの有無(=Check_val)をCheck_list_valに格納しています。

以上をfor文で5回繰り返しています。

イメージとしては,

Check_list=[タスク1,タスク2,タスク3,タスク4,タスク5,]

Check_list_val=[False,False,False,False,False]

のイメージです。それぞれの順番が対応しています.

ここで例えばタスク4のチェックボックスにチェックを入れたら下のようにタスク4に対応する部分だけTrueになるようなイメージです。

Check_list=[タスク1,タスク2,タスク3,タスク4,タスク5,]

Check_list_val=[False,False,False,True,False]

そのためCheck_list_valをget()で先頭から順番にFalseかTrueか判定していけば,各タスクのチェック有無が判別できることになります。

例えばfor文とif文を用いてチェックの有無を判別し処理を変えるこコードは以下になります.

for i in len(Check_list_val): 

      if Check_list_val[i].get()==True:

         処理A

     else:

        処理B

 

1行目はCheck_list_valは5つ要素があるのでlen(Check_list_val)=5,すなわち5回ループすることになります。

2行目からまず最初のループではi=0なのでCheck_list_val[0].get()はCheck_list_val=[False,False,False,True,False]の一番先頭(赤字)のFalseになります.よってTrueでは無いので,処理Bを実行することになります。

2回目(i=1),3回目(i=2)のループも同様にFalseなので処理Bになります。

4回目(i=3)のループではTrueなので処理Aが実行されます。

5回目(i=4)はFalseなので処理Bです。

このようにして処理を切り分けていくことができます。

 

3.次回

今回はget()でチェックの有無を判別し,チェックの有無で処理を変える方法を説明しました。次回はpart1とpart2を合わせて機能を完成させたいと思います。