初心者でもPythonを使ってみよう

趣味と実益を兼ねたPython学習記

【スポンサーリンク】



tkinter Checkbuttonの使い方 Python

tkinterで利用できる、Checkbuttonの使い方を実際にコードを書きながらまとめました。

目次

アプリ概要

Checkbuttonを用いて、ボタンの状態(無効or有効)を切り替えるアプリを作成してみます。

以下に、アプリ起動時の画面を示します。

f:id:vigilantPotato:20190327211030j:plain

上から、ボタンとチェックボタンを並べてあります。

下のチェックボタンをクリックしてチェックを入れると、下図の様に変化します。

f:id:vigilantPotato:20190327211044j:plain

ボタンのタイトルが灰色になって無効化し、クリックできない状態になります。

チェックボタンのチェックを外すと再び有効になり、ボタンをクリックすることができるようになります。

また、一つのチェックボタンで、複数のウィジェットの状態を切り替えることも可能です。

以下の例では、3つのボタンが並べてあり、チェックボタンは1つだけです。

f:id:vigilantPotato:20190327212016j:plain

しかし、先ほどと同様にチェックボタンにチェックを入れると、すべてのボタンが無効化されます。

f:id:vigilantPotato:20190327212027j:plain

チェックボタンを用いて、他ウィジェットの状態を操作する機能を実装することができました。

コードの解説

まずはモジュールのインポートです。今回使用するモジュールはtkinterのみです。

import tkinter

次に、状態切り替え用チェックボタンのクラスを作成します。クラス名は、「WidgetStateChanger」としました。

class WidgetStateChanger(tkinter.Checkbutton):  #1
    #ウィジェットのstateを切り替えるチェックボタン
    def __init__(self, text, widget=False, master=None):    #2
        self.var = tkinter.BooleanVar()                     #3
        super().__init__(master, text=text, variable=self.var)  #4
        self.bind("<Button-1>", self.change_state)  #5
        self.widget = []    #6
        if widget:  #7
            self.widget = [widget]

    def change_state(self, event):  #8
        #チェック時、ウィジェットを無効化
        if len(self.widget) != 0:   #9
            for w in self.widget:   #10
                if self.var.get():  #11
                    w["state"] = "active"   #12
                else:
                    w["state"] = "disable"  #13

    def add_widget(self, widget):   #14
        #対象ウィジェットの追加
        self.widget.append(widget)  #15
  1. tkinter.Checkbuttonを継承させた、状態切り替え用チェックボタンクラス
  2. 引数に、タイトルの文字列(text)と、状態切り替え対象のウィジェット(widget、任意)をとる
  3. チェックボタンの状態判定用インスタンス変数
  4. tkinter.Checkbuttonクラスを上書きし、オプション「text」と「variable」を設定
  5. チェックボタンクリック時に、「change_state」メソッドを実行するように設定
  6. 無効化するウィジェットのリスト
  7. ウィジェットが入力された場合、リストに追加
  8. チェックボタンクリック時に、ウィジェットを無効化するメソッド
  9. 無効化するウィジェットリストが空でない場合、状態を切り替える命令を実行
  10. リスト内の各ウィジェットについて状態を切り替える命令を実行
  11. 現在のチェックボタンの状態を取得
  12. クリック時にチェックがある場合(クリックでチェックが外れる場合)、ウィジェットを有効化
  13. クリック時にチェックがない場合(クリックでチェックが入る場合)、ウィジェットを無効化
  14. 状態切り替えリストにウィジェットを追加するメソッド
  15. 状態切り替えリストにウィジェットを追加

チェックボタンの状態は、「variable」オプションに、ブール変数(tkinter.BooleanVar)を設定しておくことで、.get()メソッドで取得できるようになります。

今回なら、self.var.get()でチェックボタンの状態を取得しています。

また、ウィジェットの状態は、「state」オプションを「active」か「disable」にすることで操作しています。

最後に、状態を切り替える対象となるウィジェットと、「WidgetStateChanger」を生成すれば完成です。

以下の例では、ボタン一つと、その状態を切り替えるチェックボタンを並べています。

if __name__ == '__main__':
    root = tkinter.Tk()
    button = tkinter.Button(master=root, width=15, text="test button") #1
    button.pack()
    checkbutton = WidgetStateChanger(master=root, text="disable", widget=button) #2     
    checkbutton.pack()
    root.mainloop()
  1. ボタン生成
  2. ボタンを引数に渡し、状態切り替え用チェックボタンを生成

上記の例では、「WidgetStateChanger」の生成時に無効化するウィジェットを渡していますが、後からadd_widgetメソッドを用いて渡すことも可能です。

一つのチェックボタンで無効化したいウィジェットが複数個ある場合、このadd_widgetメソッドを活用したほうが便利です。

以下は、3つのボタンと1つのチェックボタンを生成し、チェックボタンですべてのボタンの状態を切り替える例です。

if __name__ == '__main__':
    root = tkinter.Tk()
    checkbutton = WidgetStateChanger(master=root, text="disable") #1
    buttons = ["test1", "test2", "test3"] #2
    for b in buttons: #3
        button = tkinter.Button(master=root, width=15, text=b) #4
        checkbutton.add_widget(button) #5
        button.pack()
    checkbutton.pack()
    root.mainloop()
  1. 状態切り替え用チェックボタンを生成(引数無し)
  2. 生成するボタンのタイトルリスト
  3. for文でボタンリストを回す
  4. ボタンを生成
  5. add_widgetメソッドで、無効化ウィジェットリストに追記

コード全文

  • ボタン1つの例
import tkinter

class WidgetStateChanger(tkinter.Checkbutton):
    #ウィジェットのstateを切り替えるチェックボタン
    def __init__(self, text, widget=False, master=None):  #1
        self.var = tkinter.BooleanVar() #2
        super().__init__(master, text=text, variable=self.var)
        self.bind("<Button-1>", self.change_state)
        self.widget = []
        if widget:
            self.widget = [widget]

    def change_state(self, event):
        #チェック時、ウィジェットを無効化
        if len(self.widget) != 0:
            for w in self.widget:
                if self.var.get():  #6
                    w["state"] = "active"   #7
                else:
                    w["state"] = "disable"  #8

    def add_widget(self, widget):
        #対象ウィジェットの追加
        self.widget.append(widget)


if __name__ == '__main__':
    root = tkinter.Tk()
    button = tkinter.Button(master=root, width=15, text="test button")
    button.pack()
    checkbutton = WidgetStateChanger(master=root, text="disable", widget=button)     
    checkbutton.pack()
    root.mainloop()
  • 複数ボタンの例
import tkinter

class WidgetStateChanger(tkinter.Checkbutton):
    #ウィジェットのstateを切り替えるチェックボタン
    def __init__(self, text, widget=False, master=None):  #1
        self.var = tkinter.BooleanVar() #2
        super().__init__(master, text=text, variable=self.var)
        self.bind("<Button-1>", self.change_state)
        self.widget = []
        if widget:
            self.widget = [widget]

    def change_state(self, event):
        #チェック時、ウィジェットを無効化
        if len(self.widget) != 0:
            for w in self.widget:
                if self.var.get():  #6
                    w["state"] = "active"   #7
                else:
                    w["state"] = "disable"  #8

    def add_widget(self, widget):
        #対象ウィジェットの追加
        self.widget.append(widget)


if __name__ == '__main__':
    root = tkinter.Tk()

    checkbutton = WidgetStateChanger(master=root, text="disable")    
    
    buttons = ["test1", "test2", "test3"]
    for b in buttons:
        button = tkinter.Button(master=root, width=15, text=b)
        checkbutton.add_widget(button)
        button.pack()
    
    checkbutton.pack()
    root.mainloop()