Python(tkinter002: LabelFrame, ラジオボタンの関数, 他)

■tkinterのサンプルコードの改修2
前回から続けてtkinterのコードを修正中。今回、次のような修正を試してみた。
1.LabelFrameでラジオボタンをまとめる。
2.ラジオボタンの選択を変えたときに、他のラベルなどを変更する関数を追加する。
3.Gridを使った配置の改善(padding)。

では、まず1から。
前回もラジオボタンを触ったけど、調べてみると、LabelFrameというウィジットでまとめることができるそう。今までは2次関数のみ対応してきたけど、ラジオボタンでsinやlogといった関数にも切り替えれるようにしていく。
LabelFrameを使ったコードが下のもの。

        self.LF1 = ttk.LabelFrame(self, text='Function', background='red')
        self.LF1.grid(column=0, row=0, columnspan=8, padx=10, pady=1)

        self.LF_var = ttk.StringVar()
        graph_kinds = ('quad', 'sin', 'log')
        LF_column = 0
        for kind in graph_kinds:
            radio = ttk.Radiobutton(self.LF1, text=kind, value=LF_column, variable=self.LF_var,
                                    command=self.setFunction, background='yellow')
            radio.grid(column=LF_column, row=0, ipadx=10, ipady=10)
            LF_column += 1
        self.LF_var.set(0)

枠との区切りが分かりやすいように背景色を設定している。LabelFrameを作った後、ラジオボタンを3つ作り、LabelFrameの上にのせる。コード自体はネットを参考にしているけど、ここでfor文を使って複数のウィジットを作成できることが分かった。ウィジットを入れている変数が同じになっても問題ないのかな。
実行結果が下のもの。LabelFrameの背景色を赤、各ラジオボタンの背景色を黄色にしているので、ラジオボタンが上にのってるよう。

これで、3つのラジオボタンを作成した。その下のラベルで式を表示しているけど、ラジオボタンのチェックを変えることで、式の表示と入力できるテキストボックスを変更したい。そのためにsetFunctionとして新しく関数を定義した。上のコードのように、command=self.setFunction でラジオボタンと紐づけている。

    def setFunction(self):
        var = int(self.LF_var.get())
        if var == 0:
            self.widgt1.configure(text="y = a * x^2 + b * x + c")
            self.widgt1.text = "y = a * x^2 + b * x + c"
            self.widgt3.configure(state="normal")
            self.widgt4.configure(state="normal")
        elif var == 1:
            self.widgt1.configure(text="y = a * sin(x)")
            self.widgt1.text = "y = a * sin(x)"
            self.widgt3.configure(state="disable")
            self.widgt4.configure(state="disable")
        elif var == 2:
            self.widgt1.configure(text="y = a * log(x) + b")
            self.widgt3.configure(state="normal")
            self.widgt4.configure(state="disable")
        else:
            print("For check")

ラジオボタンでチェックが入っている番号を取得して、それぞれに対してifで場合分けする。式の表示を変更して、テキストボックスの状態(state)をdisable, normalと変更することで、入力可否を分けている。2次関数はa, b, cの3つの定数を入力するようにテキストボックスを3つ作ったけど、他の関数では3つもいらないので入力不可とする。
実際に動かすと、ラジオボタンをチェックするたびに、式のラベルの表示が変更される。

最後に、Padding(空白の幅)の改善。
式のラベル部分(widgt1)を例にとり、Gridのipadx, ipady, padx, padyの設定を少しずつ変えてどうなるか見てみた。ラベルはFrameの上にのるため、Frameの背景色を青にしている。

ipadx=30, ipady=10
ipadx=10, ipady=30
padx=10, pady=30
padx=30, pady=10

x, yは、横、縦で直感的にわかる。ipadxは自身のウィジットを広げて間隔を取る方法、padxは自身の配置を動かして間隔を取る方法といった感じかな。配置について何となく分かってきた。