1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232
| #!/usr/bin/python #coding: utf-8 #Filename: calculator_GUI.py #author:邢帅坤
import tkinter as TK import re
def change(eq,count): ''' :param eq: 刚去完括号或者乘除后的格式化列表 :param count: 发生变化的元素的索引 :return: 返回一个不存在 '+-' ,'--'类的格式化列表 ''' if eq[count] == '-': if eq[count-1] == '-': eq[count-1] = '+' del eq[count] elif eq[count-1] == '+': eq[count-1] = '-' del eq[count] return eq
def remove_multiplication_division(eq): ''' :param eq: 带有乘除号的格式化列表 :return: 去除了乘除号的格式化列表 ''' count = 0 for i in eq: if i == '*': if eq[count+1] != '-': eq[count-1] = float(eq[count-1]) * float(eq[count+1]) del(eq[count]) del(eq[count]) elif eq[count+1] == '-': eq[count] = float(eq[count-1]) * float(eq[count+2]) eq[count-1] = '-' del(eq[count+1]) del(eq[count+1]) eq = change(eq,count-1) return remove_multiplication_division(eq) elif i == '/': if eq[count+1] != '-': eq[count-1] = float(eq[count-1]) / float(eq[count+1]) del(eq[count]) del(eq[count]) elif eq[count+1] == '-': eq[count] = float(eq[count-1]) / float(eq[count+2]) eq[count-1] = '-' del(eq[count+1]) del(eq[count+1]) eq = change(eq,count-1) return remove_multiplication_division(eq) count = count + 1 return eq
def remove_plus_minus(eq): ''' :param eq: 只带有加减号的格式化列表 :return: 计算出整个列表的结果 ''' count = 0 if eq[0] != '-' and eq[0] != '+': sum = float(eq[0]) else: sum = 0.0 for i in eq: if i == '-': sum = sum - float(eq[count+1]) elif i == '+': sum = sum + float(eq[count+1]) count = count + 1 if sum >= 0: eq = [str(sum)] else: eq = ['-',str(-sum)] return eq
def calculate(s_eq): ''' :param s_eq: 不带括号的格式化列表 :return: 计算结果 ''' if '*' or '/' in s_eq: s_eq = remove_multiplication_division(s_eq) if '+' or '-' in s_eq: s_eq = remove_plus_minus(s_eq) return s_eq
def simplify(format_list): ''' :param format_list: 输入的算式格式化列表如['60','+','7','*','8'] :return: 通过递归去括号,返回简化后的列表 '''
bracket = 0 # 用于存放左括号在格式化列表中的索引 count = 0 for i in format_list: if i == '(': bracket = count elif i == ')': temp = format_list[bracket + 1 : count] new_temp = calculate(temp) format_list = format_list[:bracket] + new_temp + format_list[count+1:] format_list = change(format_list,bracket) # 解决去括号后会出现的-- +- 问题 return simplify(format_list) # 递归去括号 count = count + 1 return format_list # 当递归到最后一层的时候,不再有括号,因此返回列表
def caculator(eq): format_list = eq_format(eq) s_eq = simplify(format_list) ans = calculate(s_eq) if len(ans) == 2: ans = -float(ans[1]) else: ans = float(ans[0]) return ans
# 获得按下的数字或者符号 def getnum(num): temp = equation.get() temp2 = result.get() print(temp) print(temp2) if temp2 != ' ': temp = '0' temp2 = ' ' result.set(temp2) if (temp=='0'): temp = '' temp = temp + num equation.set(temp) print(equation)
# 按下Mc键时,去除最后一个字符 def clear(): equation.set('0') result.set('0')
# 按下Mr时,调出上次运算的结果 def get_last_result(): equation.set(last_result) result.set(0)
# 按下等于号时计算结果 def run(): global last_result temp = equation.get() temp = temp.replace('x','*') temp = temp.replace('÷','/') print(temp) answer = caculator(temp) answer = '%.2f'%answer result.set(str(answer)) last_result = answer
def eq_format(eq): ''' :param eq: 输入的算式字符串 :return: 格式化以后的列表,如['60','+','7','*','8'] ''' format_list = re.findall('[\d\.]+|\(|\+|\-|\*|\/|\)',eq) return format_list
# 主窗口 root = TK.Tk() # 创建TK实例 root.title("邢帅坤的计算器") # 设置窗口的显示名字 root.resizable(0,0) # 设置主窗口的宽度和高度是否可以通过鼠标进行拉伸改变,此处设置为不能 root.geometry('320x420') # 这里设置主窗口的初始尺寸,因为我们在上面设定了主窗口大小 不可变,因此这个尺寸也就是主窗口一直不变的尺寸了
result = TK.StringVar() # 用来显示结果的可变文本 equation = TK.StringVar() # 用来显示算式的可变文本 result.set(' ') # 赋初始值 equation.set('0') # 赋初始值
# 结果显示框 show_uresult = TK.Label(root,bg='white',fg = 'black',font = ('Arail','15'),bd='0',textvariable =equation,anchor='se') show_dresult = TK.Label(root,bg='white',fg = 'black',font = ('Arail','30'),bd='0',textvariable=result,anchor='se') show_uresult.place(x='10',y='10',width='300',height='50') show_dresult.place(x='10',y='60',width='300',height='50')
# 按钮 # 第一行按钮 button_Mc =TK.Button(root,text='Mc',bg='DarkGray',command=clear) button_Mc.place(x = '10',y='150',width = '60',height='40') button_Mr =TK.Button(root,text='Mr',bg='DarkGray',command = get_last_result) button_Mr.place(x = '90',y='150',width = '60',height='40') button_lbracket=TK.Button(root,text='(',bg='DarkGray',command= lambda : getnum('(')) button_lbracket.place(x = '170',y='150',width = '60',height='40') button_rbracket=TK.Button(root,text=')',bg='DarkGray',command= lambda : getnum(')')) button_rbracket.place(x = '250',y='150',width = '60',height='40') # 第二行按钮 button_7 =TK.Button(root,text='7',bg='DarkGray',command= lambda : getnum('7')) button_7.place(x = '10',y='205',width = '60',height='40') button_8 =TK.Button(root,text='8',bg='DarkGray',command= lambda : getnum('8')) button_8.place(x = '90',y='205',width = '60',height='40') button_9 =TK.Button(root,text='9',bg='DarkGray',command= lambda : getnum('9')) button_9.place(x = '170',y='205',width = '60',height='40') button_division =TK.Button(root,text='÷',bg='DarkGray',command= lambda : getnum('÷')) button_division.place(x = '250',y='205',width = '60',height='40') # 第三行按钮 button_4 =TK.Button(root,text='4',bg='DarkGray',command= lambda : getnum('4')) button_4.place(x = '10',y='260',width = '60',height='40') button_5 =TK.Button(root,text='5',bg='DarkGray',command= lambda : getnum('5')) button_5.place(x = '90',y='260',width = '60',height='40') button_6 =TK.Button(root,text='6',bg='DarkGray',command= lambda : getnum('6')) button_6.place(x = '170',y='260',width = '60',height='40') button_multiplication =TK.Button(root,text='X',bg='DarkGray',command= lambda : getnum('x')) button_multiplication.place(x = '250',y='260',width = '60',height='40') # 第四行按钮 button_1 =TK.Button(root,text='1',bg='DarkGray',command= lambda :getnum('1')) button_1.place(x = '10',y='315',width = '60',height='40') button_2 =TK.Button(root,text='2',bg='DarkGray',command= lambda : getnum('2')) button_2.place(x = '90',y='315',width = '60',height='40') button_3 =TK.Button(root,text='3',bg='DarkGray',command= lambda : getnum('3')) button_3.place(x = '170',y='315',width = '60',height='40') button_minus =TK.Button(root,text='—',bg='DarkGray',command= lambda : getnum('-')) button_minus.place(x = '250',y='315',width = '60',height='40') # 第五行按钮 button_0 =TK.Button(root,text='0',bg='DarkGray',command= lambda : getnum('0')) button_0.place(x = '10',y='370',width = '60',height='40') button_point =TK.Button(root,text='.',bg='DarkGray',command= lambda : getnum('.')) button_point.place(x = '90',y='370',width = '60',height='40') button_equal=TK.Button(root,text='=',bg='DarkGray',command= run) button_equal.place(x = '170',y='370',width = '60',height='40') button_plus =TK.Button(root,text='+',bg='DarkGray',command= lambda : getnum('+')) button_plus.place(x = '250',y='370',width = '60',height='40')
# 在编写完所有的GUI与相关函数后,我们要让这个窗口不断的循环,做成一直显示的效果,如果没有这一行,主窗口会出现一瞬间然后消失,像是程序没有运行一样 root.mainloop()
|