1. 程式人生 > >利用Tkinter和eval函式實現複雜計算器

利用Tkinter和eval函式實現複雜計算器

利用Tkinter和eval函式實現複雜計算器

一、架構與思路

A.使用eval函式後,計算器程式較原先版本,程式碼量大幅減少,同時可以支援多個運算元的運算
B.對AC與DEL功能進行修改,通過新增判斷指示,優化原始程式碼,減少出錯率

(1)tkinter建立主介面:

  • 設定主要的視窗,定義大小,顯示介面等;

(2)使用Button建立按鈕:

  • 數字按鈕:定義0-9數字按鈕,繫結相應邏輯函式;
  • 功能按鈕:定義小數點、百分號、AC、del、四則運算等功能按鈕,繫結相應函式;

(3)建立函式

  • 數字按鈕函式
  • 功能按鈕函式
  • 等於按鈕函式:實現最終的表示式轉換與計算,顯示計算結果

介面展示:

在這裡插入圖片描述

程式架構和思路如下:
在這裡插入圖片描述

二、程式碼實現

根據上述思路,利用python實現複雜計算器功能,程式碼如下:

import tkinter

# 建立tkinter主視窗
root = tkinter.Tk()
root.minsize(320,600)
root.title('Calculator')

# 分屏顯示結果,up顯示計算式子,down顯示數字與最終結果
result_down = tkinter.StringVar()
result_down.set('0')
result_up   =
tkinter.StringVar() result_up.set('') # 顯示結果繫結標籤並定位 # bd = borderwidth 線框寬度 label_down = tkinter.Label(root, font=('微軟雅黑',40), bg='#EEE9E9', bd='6', anchor='se', textvariable=result_down) label_down.place(x=0, y=200, width=320, height=80) label_up = tkinter.Label(root, font=('微軟雅黑',30), bg='#EEE9E9', bd=
'6', anchor='se', textvariable=result_up) label_up.place(x=0, y=0, width=320, height=200) # 建立數字按鈕並繫結函式 b7 = tkinter.Button(root, text='7', font=('微軟雅黑',30), bg='#EEE9E9', bd='1', command=lambda : pressNum('7')) b7.place(x=0 , y=345, width=80, height=65) b8 = tkinter.Button(root, text='8', font=('微軟雅黑',30), bg='#EEE9E9', bd='1', command=lambda : pressNum('8')) b8.place(x=80, y=345, width=80, height=65) b9 = tkinter.Button(root, text='9', font=('微軟雅黑',30), bg='#EEE9E9', bd='1', command=lambda : pressNum('9')) b9.place(x=160, y=345, width=80, height=65) b4 = tkinter.Button(root, text='4', font=('微軟雅黑',30), bg='#EEE9E9', bd='1', command=lambda : pressNum('4')) b4.place(x=0 , y=410, width=80, height=65) b5 = tkinter.Button(root, text='5', font=('微軟雅黑',30), bg='#EEE9E9', bd='1', command=lambda : pressNum('5')) b5.place(x=80, y=410, width=80, height=65) b6 = tkinter.Button(root, text='6', font=('微軟雅黑',30), bg='#EEE9E9', bd='1', command=lambda : pressNum('6')) b6.place(x=160, y=410, width=80, height=65) b1 = tkinter.Button(root, text='1', font=('微軟雅黑',30), bg='#EEE9E9', bd='1', command=lambda : pressNum('1')) b1.place(x=0 , y=475, width=80, height=65) b2 = tkinter.Button(root, text='2', font=('微軟雅黑',30), bg='#EEE9E9', bd='1', command=lambda : pressNum('2')) b2.place(x=80, y=475, width=80, height=65) b3 = tkinter.Button(root, text='3', font=('微軟雅黑',30), bg='#EEE9E9', bd='1', command=lambda : pressNum('3')) b3.place(x=160, y=475, width=80, height=65) b0 = tkinter.Button(root, text='0', font=('微軟雅黑',30), bg='#EEE9E9', bd='1', command=lambda : pressNum('0')) b0.place(x=80, y=540, width=80, height=65) # 建立功能按鈕並繫結函式 bAC = tkinter.Button(root, text='AC', font=('微軟雅黑',30), fg='orange', bg='#EEE9E9', bd='1', command=lambda :pressCompute('AC')) bAC.place(x=0, y=280, width=80, height=65) bdel = tkinter.Button(root, text='←', font=('微軟雅黑',30), bg='#EEE9E9', bd='1', command=lambda :pressCompute('del')) bdel.place(x=80, y=280, width=80, height=65) bdiv = tkinter.Button(root, text='÷', font=('微軟雅黑',30), bg='#EEE9E9', bd='1', command=lambda :pressCompute('/')) bdiv.place(x=160, y=280, width=80, height=65) btimes = tkinter.Button(root, text='×', font=('微軟雅黑',30), bg='#EEE9E9', bd='1', command=lambda :pressCompute('*')) btimes.place(x=240, y=280, width=80, height=65) bminus = tkinter.Button(root, text='-', font=('微軟雅黑',30), bg='#EEE9E9', bd='1', command=lambda :pressCompute('-')) bminus.place(x=240, y=345, width=80, height=65) bplus = tkinter.Button(root, text='+', font=('微軟雅黑',30), bg='#EEE9E9', bd='1', command=lambda :pressCompute('+')) bplus.place(x=240, y=410, width=80, height=65) bpoint = tkinter.Button(root, text='.', font=('微軟雅黑',30), bg='#EEE9E9', bd='1', command=lambda :pressCompute('.')) bpoint.place(x=160, y=540, width=80, height=65) bpercen = tkinter.Button(root, text='%', font=('微軟雅黑',30), bg='#EEE9E9', bd='1', command=lambda :pressCompute('%')) bpercen.place(x=0, y=540, width=80, height=65) bequ = tkinter.Button(root, text='=', font=('微軟雅黑',30), bg='orange', bd='1', command=lambda :pressEqual()) bequ.place(x=240, y=475, width=80, height=130) # 初始化 # lists用於存放最終計算的式子,含數字與四則運算子(計算過程中並不會顯示) # isPressFunc用於指示是否按下運算子 lists=[] isPressFunc = False isPressDel = False # 數字按鈕繫結函式,只用於數字標籤的顯示 def pressNum(num): global lists,isPressFunc # 如果還未按下運算按鈕,則pass if isPressFunc == False: pass # 如果已經按下,則將之前的結果清零,指示值重設為False else: result_down.set('0') isPressFunc = False # 將原有數字存為oldnum,如果為0,則新按數字為顯示結果,若不為0,則老“拼接”新為顯示結果 oldnum = result_down.get() if oldnum == '0': result_down.set(num) else: newnum = oldnum + num result_down.set(newnum) # 功能按鈕繫結函式,用於式子的元件與隱形的邏輯 def pressCompute(func): global lists,isPressFunc,isPressDel num = result_down.get() # 如果為刪除,則顯示的數字刪除一位,重新顯示,然後將結果新增的lists中 # 同時,將刪除指示調整為True,以保證刪除後螢幕顯示的數值不在其他函式被重新新增到list中 # 直到遇到其他四則運算子,將指示重置為False,否則equal函式就不能獲取後續的顯示值 if func == 'del': a = num[0:-1] result_down.set(a) num = result_down.get() #lists.remove(lists.size()-1) #del lists[-1] lists.append(num) isPressDel = True elif func == 'AC': lists.clear() result_down.set('0') result_up.set('') isPressDel = False isPressFunc = False else: if isPressDel != True: lists.append(num) lists.append(func) isPressFunc = True isPressDel = False # 一旦出現四則運算,則之前刪除指示重置為False # 等號按鈕的繫結函式,使用eval函式進行計算,並將兩個結果分別投到螢幕上 def pressEqual(): global lists,isPressFunc,isPressDel # 獲取最後一次輸入的數值 num_nd = result_down.get() # 如果該數值之前被del功能刪除過後(指示值為True),會自動新增進列表,則此時不需要再新增 # 如果是其他功能的話,則需要將該數值新增進列表 if isPressDel != True: lists.append(num_nd) # 使用join函式將單獨分離的lists列表合成字串,其中‘’空字串代表用來合成時使用的間隔為空 equation = ''.join(lists) # 使用eval函式返回傳入字串的表示式的結果。eval()實現list、dict、tuple與str之間的轉化 resultNum = eval(equation) # 將計算結果投至下顯示屏,計算表示式投至上顯示屏 result_down.set(resultNum) result_up.set(equation) # 情況列表 lists.clear() root.mainloop()