PythonのGUI(Tkinter)を使ってプログラムを書いていると、GUI Class継承する場合に
もれなく可変引数も継承されます。
しかし、継承先のClassで引数を追加すると、継承元でエラーが発生して使いづらい状況です。
例えば、TkinterのCheckbuttonは初期値を設定する事ができません。
初期値を設定できるようなCheckbuttonを作った際の覚書。
普通に記述すると、下記のようになります。
NormalCheckbox
cv = tk.BooleanVar()
cb = tk.Checkbutton(self, parent, variable=cv)
cv.set(True) #初期値設定
しかし、私はこういう風に書きたい。
ShimplCheckbox
cb = tk.Checkbutton(self, parent, check=True)
そこで、tk.Checkbuttonを継承して、SimpleCheckを作ってみます
SimpleCheckbox.py
# Initial value = check=True or False
class SimpleCheck(tk.Checkbutton):
def __init__(self, parent, *args, **kw):
self.flag = kw.pop('check')
self.var = tk.BooleanVar()
if self.flag:
self.var.set(True)
self.txt = kw["text"]
tk.Checkbutton.__init__(self, parent, *args, **kw, variable=self.var)
def get(self):
return self.var.get()
しかし、このコードには問題があります。
それは、引数"check"を指定しなければエラーが発生するという問題です
mainloop
if __name__ == '__main__':
app = tk.Tk()
sc1 = SimpleCheck(app, check=True, text="hoge")
sc1.pack()
sc2 = SimpleCheck(app)
sc2.pack()
print(sc1.getText())
print(sc1.cget('text'))#same result
app.mainloop()
error
Traceback (most recent call last):
File "arg_test.py", line 24, in <module>
sc2 = SimpleCheck(app)
File "arg_test.py", line 7, in __init__
self.flag = kw.pop('check')
KeyError: 'check'
そこで可変引数を使った継承における、引数の取り出し方法を覚書として示す。
三項演算子を使った場合、"pass"を使うとエラーが出るようです。
SimpleCheck.py
import tkinter as tk
# Check value :check=True or False (Default False)
# Label text :text=Keword
class SimpleCheck(tk.Checkbutton):
def __init__(self, parent, *args, **kw):
self.flag = kw.pop('check') if('check' in kw) else False
self.txt = kw['text'] if('text' in kw) else ""
self.var = tk.BooleanVar()
if self.flag:
self.var.set(True)
tk.Checkbutton.__init__(self, parent, *args, **kw, variable=self.var)
def get(self):
return self.var.get()
def getText(self):
return self.txt
if __name__ == '__main__':
app = tk.Tk()
sc1 = SimpleCheck(app, check=True, text="hoge")
sc1.pack()
sc2 = SimpleCheck(app)
sc2.pack()
print(sc1.getText())
print(sc1.cget('text'))#same result
app.mainloop()
追記@shiracamusさんからアドバイス頂きまして
三項演算子を使わなくてもDicのpop第二引数で初期値を設定できるようです。
アドバイスありがとうございました。
diff
def __init__(self, parent, *args, **kw):
self.flag = kw.pop('check', False)
self.txt = kw['text'] if('text' in kw) else ""