• トップ
  • ブログ一覧
  • 【Python】Tkinterで簡易的な電卓作ってみた!
  • 【Python】Tkinterで簡易的な電卓作ってみた!

    メディアチームメディアチーム
    2021.01.26

    エンジニアになろう!

    【Python】Tkinterで簡易的な電卓作ってみた!

    Python で簡易的な電卓作りに挑戦!

    誰もが使ったことがあるであろう「電卓」。

    実は、Python で簡単に作れるんです。

    Python で GUI を作成する場合、「規則的なボタンの配列」や「内部的な処理が簡単」な電卓は、とても学習しやすいテーマ!

    ぜひ、GUI ライブラリ学習の一歩として、一緒に電卓を作ってみましょう!

    Tkinter とは?

    Tkinter」は、Python のモジュールの一つです。

    デスクトップ向けアプリを作成する際に使われるもので、ボタンやエディタなどの部品「Widgit」を使って、GUI アプリを実装することができます。

    ちなみに、Python でデスクトップアプリを作成する場合、他にも以下のようなライブラリがあります。

    1. Kivy
    2. wxPython
    3. PyQt

    今回は、主要かつ手軽に扱えることから、「Tkinter」での実装を行います。

    Tkinter を扱うことのメリット

    Tkinter の最大の特徴は、主要な OS に対応していることです。

    そのため、ユーザーの OS を気にしなくて済む、クロスプラットフォームな GUI ライブラリなのです。

    さらに、OS が Linux なら、ほとんどの場合 Python が標準搭載されているため、ソースコードを渡すだけで使えます。

    Tkinter の導入方法

    それでは、さっそく Tkinter を導入しましょう!

    Python のインストール

    Python のインストールは公式サイトから簡単にインストールできますよ。

    【Python 公式サイト】
    https://www.python.org/downloads/

    インストールが済んだら、コマンドで一度、確認してみましょう。

    1# Pythonのバージョン確認
    2Python --version

    ライブラリのインストール

    そうしたら、標準搭載の Tkinter を確認してみましょう!

    1# Tkinter のバージョン確認
    2# Python シェルを起動してください
    3Python
    4>>import tkinter
    5>>tkinter._test()

    正しくインストールされていれば、ポップアップが表示されます。

    【実装例】 Tkinter で簡易的な電卓を!

    さて、次は、実際に Tkinter を使って簡易的な電卓を作っていきましょう!

    基本的な「Tkinter」の Window を作成

    まず、基本的な空の Window だけ作ってみましょう。

    以下の画像が、空の Window の実装例です。

    基本的な「Tkinter」の Window を作成

    以下が、今回の実装例のコードです。

    1# Libraries Import
    2import tkinter as tk
    3
    4# 簡易的な電卓を作ってみた!
    5class CaluGui(object):
    6    def __init__(self, app=None):
    7        # Window Setting
    8        app.title('簡易的な電卓を作ってみた') # Window のタイトル
    9        app.geometry('400x600') # Window のサイズ
    10
    11
    12
    13def main():
    14    # Window Setting
    15    app = tk.Tk()
    16    CaluGui(app)
    17
    18    # Display
    19    app.mainloop() # Window をループで回すことで Widgit に対応できるようになる
    20
    21if __name__ == '__main__':
    22    main()

    このコードは、以下の処理を行っています。

    ライブラリのインポート

    1# Libraries Import
    2import tkinter as tk

    Python3.x では「tkinter」と全て小文字で書きます。

    ウィンドウを作成し、タイトルやサイズを設定

    1# 簡易的な電卓を作ってみた!
    2class CaluGui(object):
    3    def __init__(self, app=None):
    4        # Window Setting
    5        app.title('簡易的な電卓を作ってみた') # Window のタイトル
    6        app.geometry('300x450') # Window のサイズ

    メインループの実行

    1# Display
    2app.mainloop() # Window をループで回すことで Widgit に対応できるようになる

    拡張子「.py」で実行されているか判断

    1if __name__ == '__main__':
    2    main()

    このコードを基本として、部品を組み合わせていくことで、デスクトップアプリケーションを作成していくことができます!

    簡易的な電卓の作成

    GUI を作成するにあたって、重要なポイントは「デザイン」です。

    今回は、以下のようなデザインで作成していきます。

    簡易的な電卓の作成

    以下が、今回の実装例のコードです。

    1# Libraries Import
    2import tkinter as tk
    3from tkinter import ttk
    4
    5# Define
    6BUTTON = [
    7    ['', 'B', 'C', '/'],
    8    ['7', '8', '9', '*'],
    9    ['4', '5', '6', '-'],
    10    ['1', '2', '3', '+'],
    11    ['00', '0', '.', '=']
    12]
    13
    14SYMBOL = ['+', '-', '*', '/']
    15
    16# 簡易的な電卓を作ってみた!
    17class CaluGui(object):
    18    def __init__(self, app=None):
    19        # Define
    20        self.calc_str = '' # 計算用の文字列
    21
    22        # Window Setting
    23        app.title('簡易的な電卓を作ってみた') # Window のタイトル
    24        app.geometry('300x450') # Window のサイズ
    25
    26        # Frame Setting
    27        calc_frame = ttk.Frame(app, width=300, height=100) # 計算式と結果用のFrame
    28        calc_frame.propagate(False) # サイズが固定される
    29        calc_frame.pack(side=tk.TOP, padx=10, pady=20) # 余白の設定
    30        button_frame = ttk.Frame(app, width=300, height=400) # 計算ボタン用のFrame
    31        button_frame.propagate(False) # サイズが固定される
    32        button_frame.pack(side=tk.BOTTOM) # 余白の設定
    33
    34        # Parts Setting
    35        self.calc_var = tk.StringVar() # 計算式用の動的変数
    36        self.ans_var = tk.StringVar() # 結果用の動的変数
    37        calc_label = tk.Label(calc_frame, textvariable=self.calc_var, font=("",20)) # 計算式用のLabel
    38        ans_label = tk.Label(calc_frame, textvariable=self.ans_var, font=("",15)) # 結果用のLabel
    39        calc_label.pack(anchor=tk.E) # 右揃えで配置
    40        ans_label.pack(anchor=tk.E) # 右揃えで配置
    41
    42        for y, row in enumerate(BUTTON, 1): # Buttonの配置
    43            for x, num in enumerate(row):
    44                button = tk.Button(button_frame, text=num, font=('', 15), width=6, height=3)
    45                button.grid(row=y, column=x) # 列や行を指定して配置
    46                button.bind('<Button-1>', self.click_button) # Buttonが押された場合
    47    
    48    def click_button(self, event):
    49        check = event.widget['text'] # 押したボタンのCheck
    50
    51        if check == '=': # イコールの場合
    52            if self.calc_str[-1:] in SYMBOL: # 記号の場合、記号よりも前で計算
    53                self.calc_str = self.calc_str[:-1]
    54
    55            res = '= ' + str(eval(self.calc_str)) # eval関数の利用
    56            self.ans_var.set(res)
    57        elif check == 'C': # クリアの場合
    58            self.calc_str = ''
    59            self.ans_var.set('')
    60        elif check == 'B': # バックの場合
    61            self.calc_str = self.calc_str[:-1]
    62        elif check in SYMBOL: # 記号の場合
    63            if self.calc_str[-1:] not in SYMBOL and self.calc_str[-1:] != '':
    64                self.calc_str += check
    65            elif self.calc_str[-1:] in SYMBOL: # 記号の場合、入れ替える
    66                self.calc_str = self.calc_str[:-1] + check
    67        else: # 数字などの場合
    68            self.calc_str += check
    69
    70        self.calc_var.set(self.calc_str)
    71    
    72
    73
    74def main():
    75    # Window Setting
    76    app = tk.Tk()
    77    # Window size non resizable
    78    app.resizable(width=False, height=False)
    79    CaluGui(app)
    80    # Display
    81    app.mainloop() # Window をループで回すことで Widgit に対応できるようになる
    82
    83if __name__ == '__main__':
    84    main()

    このコードは、以下の処理を行っています。

    ライブラリのインポート

    1# Libraries Import 
    2from tkinter import ttk

    ボタンの配置や記号を定義

    1# Define
    2BUTTON = [
    3    ['', 'B', 'C', '/'],
    4    ['7', '8', '9', '*'],
    5    ['4', '5', '6', '-'],
    6    ['1', '2', '3', '+'],
    7    ['00', '0', '.', '=']
    8]
    9
    10SYMBOL = ['+', '-', '*', '/']

    画面上に部品を設置する Frame を作成

    ttk モジュールを用いて、Frame のサイズや余白を設定します。

    1# Frame Setting
    2calc_frame = ttk.Frame(app, width=300, height=50) # 計算式と結果用のFrame
    3calc_frame.propagate(False) # サイズが固定される
    4calc_frame.pack(side=tk.TOP, padx=10, pady=20) # 余白の設定
    5button_frame = ttk.Frame(app, width=300, height=400) # 計算ボタン用のFrame
    6button_frame.propagate(False) # サイズが固定される
    7button_frame.pack(side=tk.BOTTOM) # 余白の設定

    作成した Frame に部品を配置

    Tkinter のモジュール「StringVar」を使い、計算式や計算結果を動的に挿入するための変数を作成します。

    さらに、Label や Buttonの配置を行います。

    Tkinter のイベント処理「bind」を使い、クリックされた時の処理も定義しましょう。

    1# Parts Setting
    2self.calc_var = tk.StringVar() # 計算式用の動的変数
    3self.ans_var = tk.StringVar() # 結果用の動的変数
    4calc_label = tk.Label(calc_frame, textvariable=self.calc_var, font=("",20)) # 計算式用のLabel
    5ans_label = tk.Label(calc_frame, textvariable=self.ans_var, font=("",15)) # 結果用のLabel
    6calc_label.pack(anchor=tk.E) # 右揃えで配置
    7ans_label.pack(anchor=tk.E) # 右揃えで配置
    8
    9for y, row in enumerate(BUTTON, 1): # Buttonの配置
    10  for x, num in enumerate(row):
    11      button = tk.Button(button_frame, text=num, font=('', 15), width=6, height=3)
    12        button.grid(row=y, column=x) # 列や行を指定して配置
    13        button.bind('<Button-1>', self.click_button) # Buttonが押された場合

    button がクリックされた時の処理を定義

    まず、どの button が押されたことをチェックします。

    押された button が記号であるかなどの条件によって、それぞれに適した処理を設定します。

    1def click_button(self, event):
    2    check = event.widget['text'] # 押したボタンのCheck
    3
    4    if check == '=': # イコールの場合
    5        if self.calc_str[-1:] in SYMBOL: # 記号の場合、記号よりも前で計算
    6            self.calc_str = self.calc_str[:-1]
    7
    8        res = '= ' + str(eval(self.calc_str)) # eval関数の利用
    9        self.ans_var.set(res)
    10    elif check == 'C': # クリアの場合
    11        self.calc_str = ''
    12        self.ans_var.set('')
    13    elif check == 'B': # バックの場合
    14        self.calc_str = self.calc_str[:-1]
    15    elif check in SYMBOL: # 記号の場合
    16        if self.calc_str[-1:] not in SYMBOL and self.calc_str[-1:] != '':
    17            self.calc_str += check
    18        elif self.calc_str[-1:] in SYMBOL: # 記号の場合、入れ替える
    19            self.calc_str = self.calc_str[:-1] + check
    20    else: # 数字などの場合
    21        self.calc_str += check
    22
    23    self.calc_var.set(self.calc_str)

    関数 'eval'

    今回、計算で使っている関数が 'eval' とよばれる関数です。

    普段使っている、print 関数を使って以下のように書いてみましょう。

    1print('123+456')

    クォーテーションの中に書かれた文字列をそのまま出力したはずです。

    しかし、'eval' 関数を使って以下のように書いてみましょう。

    1eval('123+456')

    クォーテーションの中の文字列を計算式として、認識し、計算結果を出力します。

    さいごに

    「GUI 作成なら、Python よりもっと使いやすい言語があるじゃん…」と思う人も多いでしょう。

    しかし、Python の特徴である「記述のしやすさ」「充実したライブラリ」は、様々な機能の拡張がしやすいといったメリットもあるんです。

    Python や GUI 開発に興味がある人は、ぜひ一度試してみてくださいね!

    こちらの記事もオススメ!

    featureImg2020.07.17ライトコード的「やってみた!」シリーズ「やってみた!」を集めました!(株)ライトコードが今まで作ってきた「やってみた!」記事を集めてみました!※作成日が新し...
    featureImg2020.07.27IT・コンピューターの歴史特集IT・コンピューターの歴史をまとめていきたいと思います!弊社ブログにある記事のみで構成しているため、まだ「未完成状態」...

    ライトコードでは、エンジニアを積極採用中!

    ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。

    採用情報へ

    メディアチーム
    メディアチーム
    Show more...

    おすすめ記事

    エンジニア大募集中!

    ライトコードでは、エンジニアを積極採用中です。

    特に、WEBエンジニアとモバイルエンジニアは是非ご応募お待ちしております!

    また、フリーランスエンジニア様も大募集中です。

    background