Python Code Notes

Information by python engineer

tkinterとtkinter.ttk ウィジェットの外観を比べてみた Python

これまで、tkinterモジュールを用いてアプリを作成してきましたが、より良い外観・機能を実装するには、tknter.ttkが便利との情報がネット上にあったので、少し調べてみました。

公式サイトhttps://docs.python.org/3/library/tkinter.ttk.htmlで内容を確認してみると、tkinter.ttkでは、既存ウィジェットであるButton、Checkbutton、Entry、Frame、Label、LabelFrame、Menubutton、PanedWindow、Radiobutton、Scale、ScrollbarそしてSpinboxが含まれており、それらの外観がよりモダンになっているようです。

今回は、tkintertkinter.ttkでそれらのウィジェットの外観がどのように変化するか、実際にコードを書いて確かめてみました。

ウィジェットの外観比較

外観を比較したウィジェットは、LabelFrame、Button、Label、Checkbutton、Entry、Menubutton、Radiobutton、Scale、Scrollbarです。

最初にウィジェットを並べた画面を載せます。

上記のウィジェットを順番にデフォルトの状態で表示させているだけで、左側がtkinter、右側がttkで生成したウィジェットです。

f:id:vigilantPotato:20181228231224j:plain

確かに右側のttkウィジェットの方、がモダンで洗練されていますね。

さらにうれしいことに、ttkで作成したウィジェットの多くは、カーソルを上に乗せるとアクティブになり色が変化します。そのような細かい設定がデフォルトでされているのはありがたいですね。

上記の画面を生成したコードを以下に示します。

コード

まずは、tkintertkinter.ttkをインポートします。

import tkinter
from tkinter import ttk

次に、左側に表示させるtkinterウィジェットを生成するクラスを作成します。

class TestTkinter(tkinter.LabelFrame):
    def __init__(self, master=None):
        super().__init__(master, text="Test tkinter")
        a = tkinter.Button(self, text="Button")
        a.pack()
        b = tkinter.Label(self, text="Label")
        b.pack()
        c = tkinter.Checkbutton(self, text="Checkbutton")
        c.pack()
        d = tkinter.Entry(self, text='Entry')
        d.pack()
        e = tkinter.Menubutton(self, text="Menubutton")
        e.pack()
        g = tkinter.Radiobutton(self, text="Radiobutton")
        g.pack()
        h = tkinter.Scale(self)
        h.pack()
        i = tkinter.Scrollbar(self)
        i.pack()

LabelFrameを継承したクラスにして、中で一つずつウィジェットを生成させています。

次は、ttkウィジェットを生成するクラスです。

class TtkTest(ttk.LabelFrame):
    def __init__(self, master=None):
        super().__init__(master, text="Test ttk")
        a1 = ttk.Button(self, text="Button")
        a1.pack()
        b1 = ttk.Label(self, text="Label")
        b1.pack()
        c1 = ttk.Checkbutton(self, text="Checkbutton")
        c1.pack()
        d1 = ttk.Entry(self, text='Entry')
        d1.pack()
        e1 = ttk.Menubutton(self, text="Menubutton")
        e1.pack()
        g1 = ttk.Radiobutton(self, text="Radiobutton")
        g1.pack()
        h1 = ttk.Scale(self)
        h1.pack()
        i1 = ttk.Scrollbar(self)
        i1.pack()

ttk.widget名にしている以外はtkinterと同じですね。

但し、tkinterとttkは、名称に互換性がありますが、オプションの設定方法が異なるので注意が必要です。この点については別途調べてまとめようと思います。

最後に、上記二つのクラスを生成するコードを書いて完了です。

if __name__ == "__main__":
    root = tkinter.Tk()
    #tkinter
    f = TestTkinter(master=root)
    f.grid(row=0, column=0, sticky=tkinter.N)
    #ttk
    f1 = TtkTest(master=root)
    f1.grid(row=0, column=1, sticky=tkinter.N)
    root.mainloop()

fがtkinterのオブジェクト、f1がttkのオブジェクトで、それらをgrid()で左右に表示させています。

このコードを実行すれば、最初に示した画面が現れます。

まとめ

tkintertkinter.ttkモジュールで作成したウィジェットの外観を比較しました。tkinter.ttkの方が洗練されており、外観にこだわるならこちらの方が便利そうです。

但し、互換性は完全ではなく、オプション設定の仕様が従来と異なるようなので、そこは注意が必要ですね。

tkinter.tkkでは、従来のウィジェットに加えて、Combobox、Notebook、Progressbar、Separator、SizegripそしてTreeviewが追加されているとのことです。これらも非常に便利なようなので、いずれ調べてまとめたいと思います。