LoginSignup
9
16

More than 3 years have passed since last update.

【Python】Tkinterによる80行で作るGUIアプリ「簡易電卓」

Last updated at Posted at 2019-06-24

はじめに

こんにちは。
今回は「簡易電卓」を作っていきたいと思います。
完成するとこんな感じに動きます!

簡易電卓.gif

環境

  • Windows 10 home
  • Python 3.7.1

簡易電卓の制作

今回はまず、完成したプログラムから書いていこうと思います。

完成したプログラム

簡易電卓.py
import tkinter as tk

class Application(tk.Frame):
    def __init__(self,master):
        super().__init__(master)
        self.pack()

        master.geometry("700x155")
        master.title("簡易電卓")

        self.checkSym=False
        self.textNumber=""

        self.createButton()
        self.createCanvas()

        master.after(50, self.update)

    def createButton(self): #ボタンの配置
        tk.Button(text="AC",command=self.allclear,width=13).place(x=0, y=80)
        tk.Button(text="=",command=self.calc,width=13).place(x=100, y=80)

        tk.Button(text="+",command=lambda:self.buttonClick("+"),width=13).place(x=200, y=80)
        tk.Button(text="-",command=lambda:self.buttonClick("-"),width=13).place(x=300, y=80)
        tk.Button(text="×",command=lambda:self.buttonClick("×"),width=13).place(x=400, y=80)
        tk.Button(text="÷",command=lambda:self.buttonClick("÷"),width=13).place(x=500, y=80)
        tk.Button(text="%",command=lambda:self.buttonClick("%"),width=13).place(x=600, y=80)

        tk.Button(text="0",command=lambda:self.buttonClick(0),width=19).place(x=0, y=105)
        tk.Button(text="1",command=lambda:self.buttonClick(1),width=19).place(x=140, y=105)
        tk.Button(text="2",command=lambda:self.buttonClick(2),width=19).place(x=280, y=105)
        tk.Button(text="3",command=lambda:self.buttonClick(3),width=19).place(x=420, y=105)
        tk.Button(text="4",command=lambda:self.buttonClick(4),width=19).place(x=560, y=105)
        tk.Button(text="5",command=lambda:self.buttonClick(5),width=19).place(x=0, y=130)
        tk.Button(text="6",command=lambda:self.buttonClick(6),width=19).place(x=140, y=130)
        tk.Button(text="7",command=lambda:self.buttonClick(7),width=19).place(x=280, y=130)
        tk.Button(text="8",command=lambda:self.buttonClick(8),width=19).place(x=420, y=130)
        tk.Button(text="9",command=lambda:self.buttonClick(9),width=19).place(x=560, y=130)

    def buttonClick(self,txt):
        if txt == 0 and (self.textNumber == "" or self.textNumber[-1] == "+" or self.textNumber[-1] == "-" or self.textNumber[-1] == "×" or self.textNumber[-1] == "÷"): return

        if type(txt) == int:
            self.textNumber+=str(txt)
        elif self.textNumber != "" and type(txt) == str and self.checkSym == False:
            self.textNumber+=txt
            self.checkSym = True

    def calc(self):
        if self.textNumber.find("+") != -1 and self.textNumber[-1] != "+": self.textNumber=str(int(self.textNumber[:self.textNumber.find("+")]) + int(self.textNumber[self.textNumber.find("+")+1:]))
        elif self.textNumber.find("-") != -1 and self.textNumber[-1] != "-": self.textNumber=str(int(self.textNumber[:self.textNumber.find("-")]) - int(self.textNumber[self.textNumber.find("-")+1:]))
        elif self.textNumber.find("×") != -1 and self.textNumber[-1] != "×": self.textNumber=str(int(self.textNumber[:self.textNumber.find("×")]) * int(self.textNumber[self.textNumber.find("×")+1:]))
        elif self.textNumber.find("÷") != -1 and self.textNumber[-1] != "÷": self.textNumber=str(int(self.textNumber[:self.textNumber.find("÷")]) / int(self.textNumber[self.textNumber.find("÷")+1:]))
        elif self.textNumber.find("%") != -1 and self.textNumber[-1] != "%": self.textNumber=str(int(self.textNumber[:self.textNumber.find("%")]) % int(self.textNumber[self.textNumber.find("%")+1:]))
        self.checkSym=False

    def allclear(self):
        self.textNumber=""
        self.checkSym=False

    def createCanvas(self): #キャンバスの作成
        self.canvas = tk.Canvas(self.master,width=700,height=80,bg="black")
        self.canvas.pack()
        self.resultText = self.canvas.create_text(680,40,text=self.textNumber,fill="white",font=("Helvetica",30,"bold"),anchor="e")

    def update(self):
        self.canvas.delete(self.resultText)
        self.resultText = self.canvas.create_text(680,40,text=self.textNumber,fill="white",font=("Helvetica",30,"bold"),anchor="e")

        self.master.after(50,self.update)

def main():
    win = tk.Tk()
    win.resizable(width=False, height=False) #ウィンドウを固定サイズに
    app = Application(master=win)
    app.mainloop()

if __name__ == "__main__":
    main()

こちらが完成したプログラムになります。うまく動作したでしょうか。
ここから、ウィンドウの作成と、createButtonメソッド、createCanvasメソッドについて説明していきます。

ウィンドウの作成

サイズは700×155です。タイトル名は簡易電卓です。
ウィンドウの作り方の詳しい内容はPythonによるTkinterを使った雛形(クラス化手法)の記事をご参照ください。

createButtonメソッドについて

このcreateButtonメソッドによって、ボタンを配置していきます。
ボタンをクリックすることでbuttonClickメソッドや、calcメソッド、allclearメソッドを呼んでいます。

buttonClickメソッド

def buttonClick(self,txt):
    if txt == 0 and (self.textNumber == "" or self.textNumber[-1] == "+" or self.textNumber[-1] == "-" or self.textNumber[-1] == "×" or self.textNumber[-1] == "÷"): return

    if type(txt) == int:
        self.textNumber+=str(txt)
    elif self.textNumber != "" and type(txt) == str and self.checkSym == False:
        self.textNumber+=txt
        self.checkSym = True

こちらがbuttonClickメソッドになります。引数にtxtを持っています。

一つ目の判定では受け取ったtxtが0であり、実際に表示されるテキストが空欄か計算記号だった場合はreturnをしています。
これは、最初に入力する数字が0だったり、計算記号の次に入力する数字が0になることを防ぐためです。

二つ目の判定では、受け取ったtxtの型がint型かstr型で判別しており、str型の方では、さらに実際に表示されるテキストが空欄でない状態とcheckSymがFalseの時に動作するようにしています。これは、最初に計算記号を入力することを防ぐことと、計算記号を二個以上入力できないようにするためです。
そして、それぞれ実際に表示されるテキストに文字を追加するといったプログラムになっています。

calcメソッド

def calc(self):
    if self.textNumber.find("+") != -1 and self.textNumber[-1] != "+": self.textNumber=str(int(self.textNumber[:self.textNumber.find("+")]) + int(self.textNumber[self.textNumber.find("+")+1:]))
    elif self.textNumber.find("-") != -1 and self.textNumber[-1] != "-": self.textNumber=str(int(self.textNumber[:self.textNumber.find("-")]) - int(self.textNumber[self.textNumber.find("-")+1:]))
    elif self.textNumber.find("×") != -1 and self.textNumber[-1] != "×": self.textNumber=str(int(self.textNumber[:self.textNumber.find("×")]) * int(self.textNumber[self.textNumber.find("×")+1:]))
    elif self.textNumber.find("÷") != -1 and self.textNumber[-1] != "÷": self.textNumber=str(int(self.textNumber[:self.textNumber.find("÷")]) / int(self.textNumber[self.textNumber.find("÷")+1:]))
    elif self.textNumber.find("%") != -1 and self.textNumber[-1] != "%": self.textNumber=str(int(self.textNumber[:self.textNumber.find("%")]) % int(self.textNumber[self.textNumber.find("%")+1:]))
    self.checkSym=False

こちらがcalcメソッドになります。この関数で計算を行います。
まず、実際に表示されるテキストの中にある計算記号を見つけ、その記号の種類で判別をし、それぞれ計算をするプログラムになります。

allclearメソッド

この関数では、その名の通りなのですが、表示しているテキストを空欄にします。
つまり、削除するということです。

createCanvasメソッドについて

この関数でスクリーンのようなキャンバスを作成し、そこに文字を実際に表示していきます。
updateメソッドで、随時表示しているテキストを更新している感じになります。

おわりに

以上で「簡易電卓の制作」は終わりになります。
もっと簡単に作りたかったのですが、判定が少しややこしくなってしまいました。
いつもより説明を多めにしたので、よろしくお願いします。:wink:

ここまで読んでいただき、ありがとうございました。

9
16
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
16