ノンタイトル

理系大学生の雑記と備忘録

【TKinter】Labelで計算式表示機能を追加する方法【Python電卓】

f:id:mizukawa815:20211003193323p:plain
Windows7の電卓アプリを参考に以前作成した電卓にいくつか機能を追加してみたよ~。
そのうちの1つ,Labelを用いた計算式表示機能を追加する方法を紹介してくよ~。
デザインは適当。
以前作成した電卓のソースコードはこっちにあるよ。

あわせて読みたい




ソースコード

import math
import tkinter as tk

class Calculator(tk.Frame):
    #create window
    def __init__(self, master = None):
        tk.Frame.__init__(self, master)
        self.master.geometry('185x240')
        self.master.resizable(0,0)
        self.master.title('Calculator')
        self.entry = tk.Entry(self.master, justify='right')
        self.label = tk.Label(self.master, anchor='e', height=1, font=('',8), bg='white')
        self.creat_widgets()

    #input number
    def input(self, num):
        def n():
            self.entry.insert(tk.END, num)
        return n

    #four arithmetic operations
    def operations(self, ope):
        self.entry.insert(tk.END, ope)
        txt = self.entry.get()
        self.label.config(text=txt)

    #one-hundredth
    def one_hundredth(self):
        txt = self.entry.get()
        self.entry.delete(0, tk.END)
        self.entry.insert(0, eval(txt + '/100'))

    #clearall
    def clear_all(self):
        self.entry.delete(0, tk.END)
        self.label.config(text='')

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

    #square root
    def square(self):
        txt = self.entry.get()
        self.entry.delete(0, tk.END)
        self.entry.insert(0, math.sqrt(float(txt)))
        self.label.config(text='sqrt(' + txt + ')')

    #equals
    def equals(self):
        txt = self.entry.get()
        self.value = eval(self.entry.get().replace('÷', '/').replace('×', '*').replace('+', '+').replace('-', '-'))
        self.entry.delete(0, tk.END)
        self.entry.insert(0, self.value)
        self.label.config(text=txt)

    #display part
    def creat_widgets(self):
        Buttons = [ 
        ['7', '8', '9'],
        ['4', '5', '6'], 
        ['1', '2', '3'], 
        ]
        for i, ro in enumerate(Buttons):
            for j, co in enumerate(ro):
                tk.Button(self.master, text=co, width=5, command=self.input(co)).grid(row=i+4, column=j)
        self.label.grid(row=0, column=0, columnspan=4, sticky='ew')
        self.entry.grid(row=1, column=0, columnspan=4, sticky='nsew')
        tk.Button(self.master, text='%', width=5, command=lambda: self.one_hundredth()).grid(row=2, column=0)
        tk.Button(self.master, text='CE', width=5, command=lambda: self.clear_all()).grid(row=2, column=1)
        tk.Button(self.master, text='⇦', width=5, command=lambda: self.clear_one()).grid(row=2, column=2, columnspan=2, sticky='ew')
        tk.Button(self.master, text='(', width=5, command=lambda: self.operations('(')).grid(row=3, column=0)
        tk.Button(self.master, text=')', width=5, command=lambda: self.operations(')')).grid(row=3, column=1)
        tk.Button(self.master, text='√', width=5, command=lambda: self.square()).grid(row=3, column=2)
        tk.Button(self.master, text='÷', width=5, command=lambda: self.operations('÷')).grid(row=3, column=3)
        tk.Button(self.master, text='×', width=5, command=lambda: self.operations('×')).grid(row=4, column=3)
        tk.Button(self.master, text='-', width=5, command=lambda: self.operations('-')).grid(row=5, column=3)
        tk.Button(self.master, text='+', width=5, command=lambda: self.operations('+')).grid(row=6, column=3)
        tk.Button(self.master, text='=', width=5, command=lambda: self.equals()).grid(row=7, column=3)
        tk.Button(self.master, text='0', width=12, command=self.input('0')).grid(row=7, column=0, columnspan=2)
        tk.Button(self.master, text='.', width=5, command=self.input('.')).grid(row=7, column=2)

calc = Calculator(tk.Tk())
calc.mainloop()




Labelで計算式表示

f:id:mizukawa815:20191222172458p:plain
今回追加したのはこの赤枠部分で囲まれた計算式を表示する機能です。

あったら便利ですよねこれ。


ではどのようにしてこの機能を追加したのか解説していきたいと思います。

Labelを作成

class Calculator(tk.Frame):
    #create_window
    def __init__(self, master = None):
        tk.Frame.__init__(self, master)
        self.master.geometry('185x240')
        self.master.resizable(0,0)
        self.master.title('Calculator')
        self.entry = tk.Entry(self.master, justify='right')
        #Label作成
        self.label = tk.Label(self.master, anchor='e', height=2, font=('',8), bg='white') 
        self.creat_widgets()

ここでLabelのオプションを色々といじっています。

anchorを使って文字をどこに表示するかを東西南北で指定できます。

今回は'e'なので右寄せです。

計算式をLabelに表示

Labelの役割を四則演算子とイコールの部分で見ていきます。

    #four arithmetic operations
    def operations(self, ope):
        self.entry.insert(tk.END, ope)
        #入力フォームの式を取得
        txt = self.entry.get()
        #labelに追加
        self.label.config(text=txt)

getで値を取得することができます。

この部分では任意の四則演算子が入力されたらgetで取得した計算式をtxtに代入し,configを用いてLabelに表示しています。

f:id:mizukawa815:20191222174111p:plain
f:id:mizukawa815:20191222174406p:plain

こうなります。


次にイコールボタンでの処理です。

    #equals
    def equals(self):
  #Labelに表示する値を取得
        txt = self.entry.get()
  #演算子の置き換え
        self.value = eval(self.entry.get().replace('÷', '/').replace('×', '*').replace('+', '+').replace('-', '-'))
  #式削除
        self.entry.delete(0, tk.END)
  #計算結果を表示
        self.entry.insert(0, self.value)
  #計算式を表示
        self.label.config(text=txt)

ここでもgetを用いて計算式を取得し,txtに代入します。

次に演算子の置き換えを行った後,evalで計算を行いその結果をvalueに代入し,次のinsertで表示しています。

四則演算子のときと同様に取得した値をconfigを使ってLabelに表示しています。

f:id:mizukawa815:20191222175949p:plain
f:id:mizukawa815:20191222180013p:plain

おまけ

括弧()とルート処理も追加してみました。

import math

    #square root
    def square(self):
        txt = self.entry.get()
        self.entry.delete(0, tk.END)
        self.entry.insert(0, math.sqrt(float(txt)))
        self.label.config(text='sqrt(' + txt + ')')

mathモジュールのsqrt関数を使用することでルート計算が可能になります。