实现思路
一、界面设计
二、实现功能函数
三、重构布局代码
四、按键回调函数绑定
具体实现过程
一)选择语言
考虑到个人没有接触过C++图形界面的操作,故一开始选择的是JAVA。但在实际设计过程中经过多次实践后仍屡屡碰壁,没有实现“(”、“)”的具体功能,或在界面操作上有所障碍,最后选择了Python。
二)界面设计
1.创建界面
创建一个400x400的窗口,并且设置标题。
from tkinter import *
app=Tk()
#界面布置
app.geometry('400x400')
app.wm_title("Calculator")
2.添加控件
尝试添加一个标签和按键。
#显示框
label=Label(app,text="Enter numbers",relief='ridge',font=('Arail','15'),anchor=E)
label.place(x=0,y=0,width=400,height=60,)
#添加一个按键
button=Button(
app,
text="7",
font=('Arial','14'),
)
button.place(x=0,y=60,width=100,height=60)
3.完善界面
利用循环添加多个按键。
button_txt=[
['7','8','9','+'],
['4','5','6','-'],
['1','2','3','*'],
['(',')','0','/'],
['AC','CE','.','='],
]
#显示框
label=Label(app,text="Enter numbers",relief='ridge',font=('Arail','15'),anchor=E)
label.place(x=0,y=0,width=400,height=60,)
#布局
for i in range(5):
for j in range(4):
button=Button(
app,
text=button_txt[i][j],
font=('Arial','14'),
)
button.place(x=100*j,y=60*i+60,width=100,height=60)
#循环
app.mainloop()
三)实现功能函数
功能1:按下“1、2、3、4、5、6、7、8、9、0”和“+、-、*、/、(、)”按钮,按钮的文字内容显示到标签。
功能2:按下AC按钮,将标签的内容全部置空删除。
功能3:按下CE按钮,标签往回删除一个内容。
功能4:按下=按钮直接计算结果并显示在标签区。
创建display变量表示label的字符内容。
set_content的功能为:按下某个按钮后将值传递给这个方法,这个方法会先通过display.get获取当前标签的内容,与text拼接到一起,最后重新放在到标签里面。
“”AC“”即调用clear方法,直接将标签内容设为空;
“”CE‘’即先获取当前的标签内容,通过切片的方式获取除掉最后一个字符的内容,最后将当前内容传递给display,从而实现退格效果;
“”=“”按钮按下就调用calculate方法,先获取当前标签的内容,通过eval方法计算结果,将算式和结果拼接成一个字符串返回给label显示,过程中如果出现错误异常,就显示error。
display=StringVar()
#输入
def set_content(text):
content=display.get()+text
display.set(content)
#AC
def clear():
display.set('')
#CE
def back():
display.set(str(display.get()[:-1]))
#=
def calculate():
try:
num=display.get()
res=eval(num)
display.set(num+'='+str(res))
except:
display.set('error!')
#显示框
label=Label(app,textvariable=display,relief='ridge',font=('Arail','15'),anchor=E)
label.place(x=0,y=0,width=400,height=60,)
四)重构布局代码
由于按键是循环实现的,故直接绑定回调函数不可执行。根据功能将按键分为四类,在循环现实按键时开始进行分类。
#布局
for i in range(5):
for j in range(4):
if button_txt[i][j]=="=":
button=Button(
app,
text=button_txt[i][j],
font=('Arial','14'),
)
button.place(x=100*j,y=60*i+60,width=100,height=60)
elif button_txt[i][j]=="AC":
button=Button(
app,
text=button_txt[i][j],
font=('Arial','14'),
)
button.place(x=100*j,y=60*i+60,width=100,height=60)
elif button_txt[i][j]=="CE":
button=Button(
app,
text=button_txt[i][j],
font=('Arial','14'),
)
button.place(x=100*j,y=60*i+60,width=100,height=60)
else:
button=Button(
app,
text=button_txt[i][j],
font=('Arial','14'),
)
button.place(x=100*j,y=60*i+60,width=100,height=60)
五)按键回调函数绑定
给不同类型按键绑定上对应方法。
功能1的数值和运算符号回调需要传递参数,故通过匿名函数构建了一个新函数,把之前的函数作为匿名函数表达式,从而传递参数。
#布局
for i in range(5):
for j in range(4):
if button_txt[i][j]=="=":
button=Button(
app,
text=button_txt[i][j],
font=('Arial','14'),
command=calculate
)
button.place(x=100*j,y=60*i+60,width=100,height=60)
elif button_txt[i][j]=="AC":
button=Button(
app,
text=button_txt[i][j],
font=('Arial','14'),
command=clear
)
button.place(x=100*j,y=60*i+60,width=100,height=60)
elif button_txt[i][j]=="CE":
button=Button(
app,
text=button_txt[i][j],
font=('Arial','14'),
command=back
)
button.place(x=100*j,y=60*i+60,width=100,height=60)
else:
button=Button(
app,
text=button_txt[i][j],
font=('Arial','14'),
command=lambda text=button_txt[i][j]:set_content(text)
)
button.place(x=100*j,y=60*i+60,width=100,height=60)
完整代码
from tkinter import *
app=Tk()
#界面布置
app.geometry('400x400')
app.wm_title("Calculator")
button_txt=[
['7','8','9','+'],
['4','5','6','-'],
['1','2','3','*'],
['(',')','0','/'],
['AC','CE','.','='],
]
display=StringVar()
#输入
def set_content(text):
content=display.get()+text
display.set(content)
#AC
def clear():
display.set('')
#CE
def back():
display.set(str(display.get()[:-1]))
#=
def calculate():
try:
num=display.get()
res=eval(num)
display.set(num+'='+str(res))
except:
display.set('error!')
#显示框
label=Label(app,textvariable=display,relief='ridge',font=('Arail','15'),anchor=E)
label.place(x=0,y=0,width=400,height=60,)
#布局
for i in range(5):
for j in range(4):
if button_txt[i][j]=="=":
button=Button(
app,
text=button_txt[i][j],
font=('Arial','14'),
command=calculate
)
button.place(x=100*j,y=60*i+60,width=100,height=60)
elif button_txt[i][j]=="AC":
button=Button(
app,
text=button_txt[i][j],
font=('Arial','14'),
command=clear
)
button.place(x=100*j,y=60*i+60,width=100,height=60)
elif button_txt[i][j]=="CE":
button=Button(
app,
text=button_txt[i][j],
font=('Arial','14'),
command=back
)
button.place(x=100*j,y=60*i+60,width=100,height=60)
else:
button=Button(
app,
text=button_txt[i][j],
font=('Arial','14'),
command=lambda text=button_txt[i][j]:set_content(text)
)
button.place(x=100*j,y=60*i+60,width=100,height=60)
#循环
app.mainloop()