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

    広告メディア事業部広告メディア事業部
    2021.01.26

    エンジニアになろう!

    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・コンピューターの歴史をまとめていきたいと思います!弊社ブログにある記事のみで構成しているため、まだ「未完成状態」...

    広告メディア事業部

    広告メディア事業部

    おすすめ記事