from tkinter import *
import tkinter.font
from functools import partial
def get_input(entry,argu):#除了最后一行按钮,其余按钮的事件处理函数
entry.insert(END,argu)
def backspace(entry):#按钮"<-"事件处理函数
input_len=len(entry.get())#get()获取输入内容
entry.delete(input_len-1)
def clear(entry):#按钮"clear"事件处理函数
entry.delete(0,END)
def calculate(entry):#按钮"="事件处理函数
input = entry.get()
output = str(eval(input.strip()))#eval(input.strip()):eval(str)将字符串str当成有效表达式来求值并返回计算结果(返回int类型)
clear(entry)
entry.insert(END, output)
def GUI():
root=Tk()
root.title("四则运算计算器")
root.resizable(0,0)#第一个宽度为False不可改变大小,第二个高度为False不可改变大小
entry_font=tkinter.font.Font(size=12)#设置输入文本框的字体大小,相应的会改变输入文本框的大小
entry=Entry(root,justify="right",font=entry_font)#输入框,justify="right"表示多行文本的对齐方式是右对齐
#网格布局
entry.grid(row=0,column=0,columnspan=4,sticky=N,padx=5,pady=5)#输入框entry放置在0行0列,columnspan列跨度为4列;
#sticky属性表示紧贴单元格的北角,padx/pady表示输入框
#entry与窗口root在x和y方向的填充空间大小
button_font=tkinter.font.Font(size=10,weight=tkinter.font.BOLD)#size为字体大小
#weight="bold"(粗体)或"normal"(正常)
#slant="italic"(斜体)或"normal"(正常)
#underline=1(下划线)或0(正常)
#overstrike=1(删除线)或0(正常)
button_bg="#9932CC"#RGB颜色表,按钮显示为紫色
button_press_bg='#B3EE3A'#按钮按下时显示的颜色
myButton=partial(Button,root,bg=button_bg,padx=10,pady=3,activebackground=button_press_bg)
#partial函数的作用就是:将所作用的函数作为partial()函数的第一个参数,原函数
#的各个参数依次作为partial()函数的后续参数,原函数有关键字参数的一定要带上关
#键字,没有的话,按原有参数顺序进行补充。(类似于,装饰器decorator,对于函数进
#行二次包装,产生特殊效果;但又不同于装饰器,偏函数产生了一个新函数,而装饰器,
#可改变被装饰函数的函数入口地址也可以不影响原函数)。使用偏函数作用在于简化原函数调用
button7=myButton(text='7',command=lambda : get_input(entry,'7'))
button7.grid(row=1,column=0,pady=5)#1行0列,pady为按键7与其下面的4按键间隔
button8=myButton(text='8',command=lambda : get_input(entry,'8'))
button8.grid(row=1,column=1,pady=5)#1行1列
button9=myButton(text='9',command=lambda : get_input(entry,'9'))
button9.grid(row=1,column=2,pady=5)#1行2列
button_add=myButton(text='+',command=lambda : get_input(entry,'+'))
button_add.grid(row=1,column=3,pady=5,padx=2)#1行3列
button4=myButton(text='4',command=lambda : get_input(entry,'4'))
button4.grid(row=2,column=0,pady=5)#2行0列
button5=myButton(text='5',command=lambda : get_input(entry,'5'))
button5.grid(row=2,column=1,pady=5)#2行1列
button6=myButton(text='6',command=lambda : get_input(entry,'6'))
button6.grid(row=2,column=2,pady=5)#2行2列
button_subtract=myButton(text='-',command=lambda : get_input(entry,'-'))
button_subtract.grid(row=2,column=3,pady=5)#2行3列
button1=myButton(text='1',command=lambda : get_input(entry,'1'))
button1.grid(row=3,column=0,pady=5)#3行0列
button2=myButton(text='2',command=lambda : get_input(entry,'2'))
button2.grid(row=3,column=1,pady=5)#3行1列
button3=myButton(text='3',command=lambda : get_input(entry,'3'))
button3.grid(row=3,column=2,pady=5)#3行2列
button_multiply=myButton(text='*',command=lambda : get_input(entry,'*'))
button_multiply.grid(row=3,column=3,pady=5)#3行3列
button0=myButton(text='0',command=lambda : get_input(entry,'0'))
button0.grid(row=4,column=0,columnspan=2,pady=5,sticky=N+S+E+W,padx=2)#4行0-1列,x方向与其它空间的距离为3,columnspan常与sticky配合使用,将组件紧贴单元格的某一角
button_point=myButton(text='.',command=lambda : get_input(entry,'.'))
button_point.grid(row=4,column=2,pady=5)#4行2列,由于在同一行中,第0列和第1列合并,此处column=2,否则会覆盖
button_divide=myButton(text='/',command=lambda : get_input(entry,'/'))
button_divide.grid(row=4,column=3,pady=5)#4行3列
button_back=myButton(text='<-',command=lambda : backspace(entry))
button_back.grid(row=5,column=0,pady=5)#5行0列
button_clear=myButton(text='clear',command=lambda : clear(entry))
button_clear.grid(row=5,column=1,pady=5)#5行1列
button_equal=myButton(text='=',command=lambda : calculate(entry))
button_equal.grid(row=5,column=2,columnspan=2,padx=3,pady=5,sticky=N+S+E+W)#5行2-3列
root.mainloop()
if __name__ == "__main__":
GUI()
输出: