基于Tkinter的简单计算器开发
V1.0
import tkinter
def on_screen(s: str):
screen['text'] += s
def calculate():
screen['text'] = str(eval(screen['text']))
root = tkinter.Tk()
root.title("Calculators")
root.geometry('410x300')
screen = tkinter.Label(text='')
screen.place(x=100, y=50, width=150, height=50)
tkinter.Button(text='1', command=lambda: on_screen("1")).place(x=100, y=100, width=75, height=30)
tkinter.Button(text='2', command=lambda: on_screen("2")).place(x=175, y=100, width=75, height=30)
tkinter.Button(text='3', command=lambda: on_screen("3")).place(x=250, y=100, width=75, height=30)
tkinter.Button(text='4', command=lambda: on_screen("4")).place(x=100, y=130, width=75, height=30)
tkinter.Button(text='5', command=lambda: on_screen("5")).place(x=175, y=130, width=75, height=30)
tkinter.Button(text='6', command=lambda: on_screen("6")).place(x=250, y=130, width=75, height=30)
tkinter.Button(text='7', command=lambda: on_screen("7")).place(x=100, y=160, width=75, height=30)
tkinter.Button(text='8', command=lambda: on_screen("8")).place(x=175, y=160, width=75, height=30)
tkinter.Button(text='9', command=lambda: on_screen("9")).place(x=250, y=160, width=75, height=30)
tkinter.Button(text='+', command=lambda: on_screen("+")).place(x=100, y=190, width=112, height=30)
tkinter.Button(text='-', command=lambda: on_screen("-")).place(x=212, y=190, width=112, height=30)
tkinter.Button(text='*', command=lambda: on_screen("*")).place(x=100, y=220, width=112, height=30)
tkinter.Button(text='/', command=lambda: on_screen("/")).place(x=212, y=220, width=112, height=30)
tkinter.Button(text='=', command=calculate).place(x=100, y=250, width=225, height=30)
root.update()
root.mainloop()
需要更新:
- 增加括号
- 调整界面,美化界面
- 把中间几个按键的写法改进以下,把坐标值单独做出去做成数组
Bug记录:
试图通过这种方式来简化程序的书写:
number_position = [[100, 100], [175, 100], [250, 100],
[100, 130], [175, 130], [250, 130],
[100, 160], [175, 160], [250, 160]
]
number_size = [75, 30]
tkinter.Button(text=str(i + 1), command=lambda: on_screen(str(i + 1))).place(x=number_position[i][0],
y=number_position[i][1],
width=number_size[0],
height=number_size[1])
但是实际反应出来,不管按什么键,显示的都是9,这关系到lambda的用法
按照我之前的理解,button的command属性只能赋予函数名,但是如果要调用参数的话,就只能用lambda包装成一个函数名,相当于:
command = func_name
func_name = lambda: func(x)
实际上这样也是有效的
import tkinter
def s(string):
b['text'] += string
root = tkinter.Tk()
b = tkinter.Button(text="哈", command=lambda: s("嘿"))
b.pack()
root.mainloop()
这样是可以实现预想的功能,达到button
的command
可以调参的结果
但是在这个例子里却出现了BUG,为什么?
因为赋予每一个button
的command
不是我预想的func_name = on_screen(str(1)),on_screen(str(2))
这些名字,而是实打实的on_screen(str(i+1))
那么自然所有的button.command
对应的函数名最后都是on_screen(str(9))
修改方案如下,把原来的展示函数改成返回一个函数名:
# 修改之前的展示函数
def on_screen(s: str):
screen['text'] += s
# 修改之后的展示函数,分离了函数名生成和真正的函数
def on_screen(s: str):
return lambda: show(s)
def show(s):
screen['text'] += s
再加上一些美化,和非法输入警告
V2.0
import tkinter
from tkinter import messagebox
number_position = [[100, 100], [175, 100], [250, 100],
[100, 130], [175, 130], [250, 130],
[100, 160], [175, 160], [250, 160]
]
number_size = [75, 30]
def on_screen(s: str):
return lambda: show(s)
def show(s):
screen['text'] += s
def zero():
screen['text'] = ''
def calculate():
try:
screen['text'] = str(eval(screen['text']))
except:
zero()
messagebox.showerror('Error', '请输入正确的表达式')
root = tkinter.Tk()
root.title("Calculators")
root.geometry('410x380')
screen = tkinter.Label(text='', borderwidth=5, relief=tkinter.GROOVE)
screen.place(x=100, y=50, width=228, height=50)
for i in range(9):
tkinter.Button(text=str(i + 1), command=on_screen(str(i + 1))).place(x=number_position[i][0],
y=number_position[i][1],
width=number_size[0],
height=number_size[1])
tkinter.Button(text='+', command=on_screen("+")).place(x=100, y=190, width=112, height=30)
tkinter.Button(text='-', command=on_screen("-")).place(x=212, y=190, width=112, height=30)
tkinter.Button(text='*', command=on_screen("*")).place(x=100, y=220, width=112, height=30)
tkinter.Button(text='/', command=on_screen("/")).place(x=212, y=220, width=112, height=30)
tkinter.Button(text='(', command=on_screen("(")).place(x=100, y=250, width=112, height=30)
tkinter.Button(text=')', command=on_screen(")")).place(x=212, y=250, width=112, height=30)
tkinter.Button(text='=', command=calculate).place(x=100, y=280, width=225, height=30)
tkinter.Button(text='AC', command=zero).place(x=100, y=310, width=225, height=30)
root.update()
root.mainloop()