Python tkinterで計算機を作ってみる

Python学習【365日チャレンジ!】309日目のマスターU(@Udemy11)です。

Youtubeの釣り動画を見ていると知らない間に時間が過ぎていきます。

ほんと、Youtubeって時間泥棒ですよね。

ずるずると次の動画を見てしまうので、なんとなくYoutubeを見るのはやめたほうがいいとわかっていながら見ちゃうのは、若干依存症になりかかっているような気がします。

Python学習に集中するときは、当然Macを使うので、ネットを遮断することが難しいんですよね。

時間泥棒!?のYoutubeに捕まらない方法があれば教えて下さい。

それでは今日も、Python学習を始めましょう。

昨日の復習

昨日は、GUIツールのtkinterを学習しました。

Python公式ドキュメントのtkinterのページからサンプルコードを使って、簡単なアプリケーションを動かしましたが、これらのコードを1から書けるようになるにはまだまだ経験が必要です。

ひたすらコードを書いて一つ一つ覚えていくしかないので、数稽古が重要ですね。

くわしくは昨日の記事をごらんください。

今日は、tkinterを使って、計算機アプリを作成します。

calculator.py

最初に完成したコードを書いて、あとからそれぞれの部分がどのような役割を持っているのか分解してみていきましょう

import tkinter as tk


class Application(tk.Frame):

    def __init__(self, master=None):
        super().__init__(master)
        self.master.geometry()
        self.master.title('Calculation')

        self.entry = tk.Entry(self.master)

        self.menu_bar = tk.Menu(self.master)
        self.master.config(menu=self.menu_bar)

        self.create_widgets()

    def input(self, action):
        self.entry.insert(tk.END, action)

    def clear_all(self):
        self.entry.delete(0, tk.END)

    def clear_one(self):
        txt = self.entry.get()
        self.entry.delete(0, tk.END)
        self.entry.insert(0, txt[:-1])

    def equals(self):
        self.value = eval(self.entry.get().replace('÷', '/').replace('x', '*'))
        self.entry.delete(0, tk.END)
        self.entry.insert(0, self.value)

    def create_widgets(self):
        file_menu = tk.Menu(self.menu_bar)
        file_menu.add_command(label='Exit', command=self.master.quit)
        self.menu_bar.add_cascade(label='File', menu=file_menu)

        self.entry.grid(row=0, column=0, columnspan=6, pady=3)
        self.entry.focus_set()

        tk.Button(self.master, text='7', width=3,
                  command=lambda: self.input(7)).grid(row=1, column=0)
        tk.Button(self.master, text='8', width=3,
                  command=lambda: self.input(8)).grid(row=1, column=1)
        tk.Button(self.master, text='9', width=3,
                  command=lambda: self.input(9)).grid(row=1, column=2)

        tk.Button(self.master, text='4', width=3,
                  command=lambda: self.input(4)).grid(row=2, column=0)
        tk.Button(self.master, text='5', width=3,
                  command=lambda: self.input(5)).grid(row=2, column=1)
        tk.Button(self.master, text='6', width=3,
                  command=lambda: self.input(6)).grid(row=2, column=2)

        tk.Button(self.master, text='1', width=3,
                  command=lambda: self.input(1)).grid(row=3, column=0)
        tk.Button(self.master, text='2', width=3,
                  command=lambda: self.input(2)).grid(row=3, column=1)
        tk.Button(self.master, text='3', width=3,
                  command=lambda: self.input(3)).grid(row=3, column=2)

        tk.Button(self.master, text='0', width=3,
                  command=lambda: self.input(0)).grid(row=4, column=0)
        tk.Button(self.master, text='.', width=3,
                  command=lambda: self.input('.')).grid(row=4, column=1)

        tk.Button(self.master, text='x', width=3,
                  command=lambda: self.input('x')).grid(row=1, column=3)
        tk.Button(self.master, text='-', width=3,
                  command=lambda: self.input('-')).grid(row=2, column=3)
        tk.Button(self.master, text='+', width=3,
                  command=lambda: self.input('+')).grid(row=3, column=3)
        tk.Button(self.master, text='÷', width=3,
                  command=lambda: self.input('÷')).grid(row=4, column=3)

        tk.Button(self.master, text='AC', width=3,
                  command=lambda: self.clear_all()).grid(row=1, column=4)
        tk.Button(self.master, text='C', width=3,
                  command=lambda: self.clear_one()).grid(row=1, column=5)

        tk.Button(self.master, text='=', width=6,
                  command=self.equals).grid(row=4, column=4, columnspan=2)


root = tk.Tk()
app = Application(master=root)
app.mainloop()

このコードを実行すれば計算機が立ち上がります。
ちなみに、このサンプルコードは酒井さんの講座からコピーさせていただきました。

Udemy講師 酒井さん プログラミング Python

10ヶ月毎日少しずつ学習していますが、1日の学習内容が短すぎるのか、まだ最後まで学習できないくらい濃い内容になっているので、Pythonを本気で学習するのなら、受講して損はない講座であることは間違いありませんので、ぜひ受講してみてください。

コードを見てみると、クラスを作って、必要な関数を記述し、tk.TKクラスのrootインスタンスを、作成したApplicationクラスの引数に入れたappインスタンスにして、ウインドウを表示して制御するためのループに入るmainroop()を実行しています。

ループが継続しているので、ウインドウを閉じない限り、プログラムが動き続けている状態になっています。

個別にコードを見てみましょう

Application()

import tkinter as tk


class Application(tk.Frame):

1行目でtkinterをインポートしたあと、tk.Frameを継承したApplicationクラスを定義します。

__init__()

    def __init__(self, master=None):
        super().__init__(master)
        self.master.geometry()
        self.master.title('Calculation')

        self.entry = tk.Entry(self.master)

        self.menu_bar = tk.Menu(self.master)
        self.master.config(menu=self.menu_bar)

        self.create_widgets()

インスタンスが生成されるときの初期化を__init__()で定義していますが、引数のmasterのデフォルトをNoneにしています。

7行目で__init__を引数masterでオーバーライドしています。

8行目で、メイン画面の位置やサイズの情報を取得・調整できるgeometry()を使います。

9行目でウインドウのタイトルをCalculationに定義しています。

11行目で数値などの入力欄をentryとして、引数にmasterを入れたtk.Entryを代入します。

13行目で、メニューバーに表示するものをmenu_barとして、引数にmasterを入れたtk.Menuを代入します。

14行目でmaster.configの引数menuを、13行目で定義したmenu_barとしています。

16行目でcreate_widgets()を実行していますが、このcreate_widegts()は後ほど定義します。

まとめ

続いてinput()の解説に入ろうと思うのですが、【鬼滅の刃】の影響で、まぶたが閉じて、気づけば「っっっっっっっっっっっっっっっっっっっっっっっっっっっっっっっっっっっっっっっd」と入力されていました。

気持ちを取り直して解説しようとするのですが、自分で何を入力しているのかわからない文章になってしまっていたので、今日はここまでにして、明日、今日の続きを解説したいと思います。

ということで、明日もGood Python!