代码中肯定还有一些思维漏洞,望参考者留言交流。
界面:
演示视频:https://files.cnblogs.com/files/acm-jing/calculator.rar
代码:

1 # coding=utf-8 2 from tkinter import * 3 import math 4 import re 5 6 7 #the main gui 8 window=Tk() 9 window.title('Calculator') 10 window.geometry('450x260') 11 mainFrame=Frame(bg='black') 12 13 #-----------button click event 14 def ButtonClick(buttonText): #except '=',use to show the expression on the entry 15 global showRes,res,oneInput 16 if buttonText!='clear' and buttonText!='back': 17 oneInput.append(buttonText) 18 showRes=showRes+buttonText 19 elif buttonText=='clear': 20 showRes='' 21 oneInput.clear() 22 else: 23 if showRes!='': 24 showRes=showRes[0:len(showRes)-len(oneInput.pop())] 25 res.set(showRes) 26 27 def MultDiv(expression,op):#multiply and divid operations 28 loc=expression.index(op) 29 if op=='×' and expression[loc+1]!='-': 30 tempRes=float(expression[loc-1])*float(expression[loc+1]) 31 elif op=='÷' and expression[loc+1]!='-':#calculate divid,not:divisor is 0 32 tempRes = float(expression[loc-1])/float(expression[loc+1]) 33 elif op=='×' and expression[loc+1]=='-': 34 tempRes = -float(expression[loc - 1]) * float(expression[loc + 2]) 35 del expression[loc-1] 36 elif op == '÷' and expression[loc + 1] == '-': 37 tempRes = -float(expression[loc - 1]) / float(expression[loc + 2]) 38 del expression[loc - 1] 39 del expression[loc-1],expression[loc-1],expression[loc-1] 40 expression.insert(loc-1,str(tempRes)) 41 return expression 42 43 def SingelValueFunction(expression,loc): 44 op=expression[loc] 45 if op=='sin ': 46 if expression[loc+1]!='-': 47 temRes=math.sin(float(expression[loc+1])) 48 else: 49 temRes=math.sin(-float(expression[loc+2])) 50 del expression[loc] 51 elif op=='cos ': 52 if expression[loc+1]!='-': 53 temRes=math.cos(float(expression[loc+1])) 54 else: 55 temRes=math.cos(-float(expression[loc+2])) 56 del expression[loc] 57 elif op=='tan ': 58 if expression[loc+1]!='-': 59 temRes=math.tan(float(expression[loc+1])) 60 else: 61 temRes=math.tan(-float(expression[loc+2])) 62 del expression[loc] 63 elif op=='abs ': 64 if expression[loc+1]!='-': 65 temRes=float(expression[loc+1]) 66 else: 67 temRes=float(expression[loc+2]) 68 del expression[loc] 69 elif op=='ln ': 70 if expression[loc+1]!='-': 71 temRes=math.log(2.718281828,float(expression[loc+1])) 72 else: 73 temRes = math.log(2.718281828, -float(expression[loc + 2])) 74 del expression[loc] 75 elif op=='sqrt ': 76 if expression[loc+1]!='-': 77 temRes=math.sqrt(float(expression[loc+1])) 78 else: 79 temRes=math.sqrt(-float(expression[loc+2])) 80 del expression[loc] 81 # elif 82 del expression[loc],expression[loc] 83 expression.insert(loc,str(temRes)) 84 return expression 85 86 def Pi(expression,op): 87 loc = expression.index(op) 88 temRes = 3.1415926535 89 del expression[loc] 90 expression.insert(loc,temRes) 91 return expression 92 93 def E(expression,op): 94 loc=expression.index(op) 95 temRes=2.718281828 96 del expression[loc] 97 expression.insert(loc,str(temRes)) 98 return expression 99 100 def Factorial(expression,op): 101 loc=expression.index(op) 102 temRes=math.factorial(float(expression[loc-1])) 103 del expression[loc-1],expression[loc-1] 104 expression.insert(loc-1,str(temRes)) 105 return expression 106 107 def Power(expression,op): 108 loc=expression.index(op) 109 if expression[loc+1]!='-': 110 temRes=math.pow(float(expression[loc-1]),float(expression[loc+1])) 111 else: 112 temRes = math.pow(float(expression[loc - 1]), -float(expression[loc + 2])) 113 del expression[loc-1] 114 del expression[loc-1],expression[loc-1],expression[loc-1] 115 expression.insert(loc-1,str(temRes)) 116 return expression 117 118 def WithoutBracketsExpressionCalculate(strExpression): 119 expression = re.findall('([d.]+|÷|-|+|×+|sin |cos |tan |ln |abs |sqrt |π|e|!|^)', strExpression) 120 print(expression) 121 if expression[0] == '-': # negative number 122 expression[0] = expression[0] + expression[1] 123 del expression[1] 124 sum=0 125 #use value to replace the e and π 126 while 'e' in expression: 127 E(expression,'e') 128 while 'π' in expression: 129 Pi(expression,'π') 130 # calculate single value function 131 while '!' in expression: 132 Factorial(expression,'!') 133 134 singleValueFunctonIndexs=[] 135 for i in range(len(expression)): 136 if expression[i] in ['sin ','cos ','tan ','ln ','abs ','sqrt ']: 137 singleValueFunctonIndexs.append(i) 138 singleValueFunctonNums=len(singleValueFunctonIndexs) 139 for j in range(singleValueFunctonNums): 140 SingelValueFunction(expression,singleValueFunctonIndexs[singleValueFunctonNums-1-j]) 141 142 while '^' in expression: 143 Power(expression,'^') 144 145 while True: 146 #calculate mul and div first 147 if '×' in expression and '÷'not in expression: 148 MultDiv(expression,'×') 149 elif '×'not in expression and '÷'in expression: 150 MultDiv(expression,'÷') 151 elif '÷'in expression and '×'in expression: 152 locMul=expression.index('×') 153 locDiv=expression.index('÷') 154 if locMul<locDiv: 155 MultDiv(expression,'×') 156 else: 157 MultDiv(expression,'÷') 158 #calculate add and minus 159 else: 160 161 sum+=float(expression[0]) 162 163 for i in range(1,len(expression),2):#step 2 164 if expression[i]=='+' and expression[i+1]!='-': 165 sum+=float(expression[i+1]) 166 elif expression[i]=='+' and expression[i+1]=='-': 167 sum-=float(expression[i+2]) 168 elif expression[i]=='-' and expression[i+1]!='-': 169 sum-=float(expression[i+1]) 170 elif expression[i]=='-' and expression[i+1]=='-': 171 sum+=float(expression[i+2]) 172 break 173 # if(len(expression)==1): 174 # return sum 175 # else: 176 # return 'Syntax ERROR' 177 return sum 178 179 def WithBracketsExpressionCalculate(expression): 180 leftBrackes=[] #record the location of '(' 181 ans=0 182 183 if '(' not in expression: 184 ans=WithoutBracketsExpressionCalculate(expression) 185 return ans 186 187 for i in range(len(expression)): 188 if expression[i]=='(': 189 leftBrackes.append(i) 190 elif expression[i]==')': 191 subExpression=expression[leftBrackes[len(leftBrackes)-1]+1:i] 192 tempAns=WithoutBracketsExpressionCalculate(subExpression) 193 expression=expression[0:leftBrackes[len(leftBrackes)-1]]+str(tempAns)+expression[i+1:len(expression)+1] 194 leftBrackes.pop() 195 return WithBracketsExpressionCalculate(expression) 196 197 198 def ButtonEqual(): 199 global showRes,res,oneInput 200 # expression=re.findall('([d.]+|÷|-|+|×)',showRes) 201 #print(expression) 202 try: 203 showRes=str(WithBracketsExpressionCalculate(showRes)) 204 except Exception: 205 showRes='Syntax ERROR' 206 #---------use eval() to calculate the expression 207 #strExpression = '' 208 # for i in range(len(expression)): 209 # strExpression+=expression[i] 210 #showRes=eval(strExpression) 211 #---------use eval() to calculate the expression 212 #print(oneInput) 213 oneInput.clear() 214 oneInput.append(showRes) 215 res.set(showRes) 216 217 #------glaobal variabls 218 global showRes 219 global oneInput 220 global res 221 showRes='' 222 oneInput=[] 223 res=StringVar() 224 res.set(showRes) 225 226 227 #--------output 228 entryShow=Entry(mainFrame,bg='#121212',foreground='white',font=('TimesNewRoman', '15', 'normal'),borderwidth=6,width=300,textvariable=res) 229 entryShow.pack(padx=5,pady=5) 230 231 #--------function 232 233 #sin function 234 buttonSin=Button(mainFrame,command=lambda :ButtonClick(buttonText='sin '),width=3,height=1,bg='#212121',text='sin',font=('TimesNewRoman', '12', 'normal'),foreground='white') 235 buttonSin.place(x=5,y=55) 236 #ln function 237 buttonLn=Button(mainFrame,command=lambda :ButtonClick(buttonText='ln '),width=3,height=1,bg='#212121',text='ln',font=('TimesNewRoman', '12', 'normal'),foreground='white') 238 buttonLn.place(x=60,y=55) 239 #cos 240 buttonCos=Button(mainFrame,command=lambda :ButtonClick(buttonText='cos '),width=3,height=1,bg='#212121',text='cos',font=('TimesNewRoman', '12', 'normal'),foreground='white') 241 buttonCos.place(x=5,y=87) 242 #abs 243 buttonAbs=Button(mainFrame,command=lambda :ButtonClick(buttonText='abs '),width=3,height=1,bg='#212121',text='abs',font=('TimesNewRoman', '12', 'normal'),foreground='white') 244 buttonAbs.place(x=60,y=87) 245 #tan 246 buttonLog=Button(mainFrame,command=lambda :ButtonClick(buttonText='tan '),width=3,height=1,bg='#212121',text='tan',font=('TimesNewRoman', '12', 'normal'),foreground='white') 247 buttonLog.place(x=5,y=119) 248 #e 249 buttonE=Button(mainFrame,command=lambda :ButtonClick(buttonText='e'),width=3,height=1,bg='#212121',text='e',font=('TimesNewRoman', '12', 'normal'),foreground='white') 250 buttonE.place(x=60,y=119) 251 #pi 252 buttonPI=Button(mainFrame,command=lambda :ButtonClick(buttonText='π'),width=3,height=1,bg='#212121',text='π',font=('TimesNewRoman', '12', 'normal'),foreground='white') 253 buttonPI.place(x=5,y=151) 254 #^ 255 buttonIndex=Button(mainFrame,command=lambda :ButtonClick(buttonText='^'),width=3,height=1,bg='#212121',text='^',font=('TimesNewRoman', '12', 'normal'),foreground='white') 256 buttonIndex.place(x=60,y=151) 257 #! 258 buttonFactorial=Button(mainFrame,command=lambda :ButtonClick(buttonText='!'),width=3,height=1,bg='#212121',text='!',font=('TimesNewRoman', '12', 'normal'),foreground='white') 259 buttonFactorial.place(x=5,y=183) 260 #sqrt 261 buttonSqrt=Button(mainFrame,command=lambda :ButtonClick(buttonText='sqrt '),width=3,height=1,bg='#212121',text='√',font=('TimesNewRoman', '12', 'normal'),foreground='white') 262 buttonSqrt.place(x=60,y=183) 263 #clear 264 buttonClear=Button(mainFrame,command=lambda :ButtonClick(buttonText='clear'),width=3,height=1,bg='#212121',text='clear',font=('TimesNewRoman', '12', 'normal'),foreground='white') 265 buttonClear.place(x=5,y=215) 266 #back 267 buttonBack=Button(mainFrame,command=lambda :ButtonClick(buttonText='back'),width=3,height=1,bg='#212121',text='back',font=('TimesNewRoman', '12', 'normal'),foreground='white') 268 buttonBack.place(x=60,y=215) 269 #---------number 270 271 #7 272 button7=Button(mainFrame,command=lambda :ButtonClick(buttonText='7'),width=3,height=2,bg='#424242',text='7',font=('TimesNewRoman', '12', 'normal'),foreground='white') 273 button7.place(x=140,y=55) 274 #8 275 button8=Button(mainFrame,command=lambda :ButtonClick(buttonText='8'),width=3,height=2,bg='#424242',text='8',font=('TimesNewRoman', '12', 'normal'),foreground='white') 276 button8.place(x=195,y=55) 277 #9 278 button9=Button(mainFrame,command=lambda :ButtonClick(buttonText='9'),width=3,height=2,bg='#424242',text='9',font=('TimesNewRoman', '12', 'normal'),foreground='white') 279 button9.place(x=250,y=55) 280 #4 281 button4=Button(mainFrame,command=lambda :ButtonClick(buttonText='4'),width=3,height=2,bg='#424242',text='4',font=('TimesNewRoman', '12', 'normal'),foreground='white') 282 button4.place(x=140,y=103) 283 #5 284 button5=Button(mainFrame,command=lambda :ButtonClick(buttonText='5'),width=3,height=2,bg='#424242',text='5',font=('TimesNewRoman', '12', 'normal'),foreground='white') 285 button5.place(x=195,y=103) 286 #6 287 button6=Button(mainFrame,command=lambda :ButtonClick(buttonText='6'),width=3,height=2,bg='#424242',text='6',font=('TimesNewRoman', '12', 'normal'),foreground='white') 288 button6.place(x=250,y=103) 289 #1 290 button1=Button(mainFrame,command=lambda :ButtonClick(buttonText='1'),width=3,height=2,bg='#424242',text='1',font=('TimesNewRoman', '12', 'normal'),foreground='white') 291 button1.place(x=140,y=151) 292 #2 293 button2=Button(mainFrame,command=lambda :ButtonClick(buttonText='2'),width=3,height=2,bg='#424242',text='2',font=('TimesNewRoman', '12', 'normal'),foreground='white') 294 button2.place(x=195,y=151) 295 #3 296 button3=Button(mainFrame,command=lambda :ButtonClick(buttonText='3'),width=3,height=2,bg='#424242',text='3',font=('TimesNewRoman', '12', 'normal'),foreground='white') 297 button3.place(x=250,y=151) 298 #0 299 button0=Button(mainFrame,command=lambda :ButtonClick(buttonText='0'),width=10,height=2,bg='#424242',text='0',font=('TimesNewRoman', '12', 'normal'),foreground='white') 300 button0.place(x=140,y=199) 301 #. 302 buttonDot=Button(mainFrame,command=lambda :ButtonClick(buttonText='.'),width=3,height=2,bg='#424242',text='.',font=('TimesNewRoman', '12', 'normal'),foreground='white') 303 buttonDot.place(x=250,y=199) 304 305 #------------operations 306 #divide 307 buttonDiv=Button(mainFrame,command=lambda :ButtonClick(buttonText='÷'),width=3,height=2,bg='#212121',text='÷',font=('TimesNewRoman', '12', 'normal'),foreground='white') 308 buttonDiv.place(x=335,y=55) 309 #left bracket 310 buttonLBracket=Button(mainFrame,command=lambda :ButtonClick(buttonText='('),width=3,height=2,bg='#212121',text='(',font=('TimesNewRoman', '12', 'normal'),foreground='white') 311 buttonLBracket.place(x=390,y=55) 312 #multiply 313 buttonMul=Button(mainFrame,command=lambda :ButtonClick(buttonText='×'),width=3,height=2,bg='#212121',text='×',font=('TimesNewRoman', '12', 'normal'),foreground='white') 314 buttonMul.place(x=335,y=103) 315 #right bracket 316 buttonRBracket=Button(mainFrame,command=lambda :ButtonClick(buttonText=')'),width=3,height=2,bg='#212121',text=')',font=('TimesNewRoman', '12', 'normal'),foreground='white') 317 buttonRBracket.place(x=390,y=103) 318 #minus 319 buttonMinus=Button(mainFrame,command=lambda :ButtonClick(buttonText='-'),width=3,height=2,bg='#212121',text='-',font=('TimesNewRoman', '12', 'normal'),foreground='white') 320 buttonMinus.place(x=335,y=151) 321 #add 322 buttonMinus=Button(mainFrame,command=lambda :ButtonClick(buttonText='+'),width=3,height=2,bg='#212121',text='+',font=('TimesNewRoman', '12', 'normal'),foreground='white') 323 buttonMinus.place(x=335,y=199) 324 #equal 325 buttonMinus=Button(mainFrame,command=ButtonEqual,width=3,height=5,bg='#212121',text='=',font=('TimesNewRoman', '12', 'normal'),foreground='white') 326 buttonMinus.place(x=390,y=151) 327 328 mainFrame.pack(expand='yes',fill='both') 329 window.mainloop()
测试样例: