Python Tkinter实现简易计算器:网格布局与事件处理详解
本文详细介绍使用Python Tkinter库开发简易计算器的全过程。重点解析网格布局(Grid)在界面设计中的应用,包括窗口尺寸、组件定位及文本框排版。深入讲解输入验证、除零错误处理及历史记录显示逻辑,并指出按钮命令绑定中常见的立即执行陷阱及其Lambda解决方案。
本文分享使用Python实现简易计算器的完整代码示例,供读者参考学习。
简易计算器
该简易计算器具备以下核心功能:
- 支持用户输入、执行计算逻辑并输出结果;
- 实现基础的加、减、乘、除四则运算;
- 针对除法运算中除数不能为零的情况进行特殊处理;
- 对空输入状态进行拦截与提示;
- 在右侧文本框中记录并展示历史计算过程。
与之前的两个项目不同,本项目采用网格布局(Grid)构建界面。虽然窗口整体风格相似,但在实际实现网格布局时遇到了不少挑战与细节问题。
窗口
实现最基础的图形界面窗口。
import tkinter as tk
import tkinter.messagebox
win = tk.Tk() #窗口名称
win.title("简易计算器")
win.geometry('650x600') # 这里的乘是小x
win.mainloop()使用geometry()方法设定窗口大小,格式为“高x宽+起始x位置+起始y位置”。例如,“600x600+50+50”表示窗口尺寸为600x600像素,起始坐标为(50, 50)。

布局
标题
使用Label控件实现标题显示。标签可展示文字、设置居中、背景色、字体字号及尺寸大小。
b=tk.Label(win, text='简易计算器',justify=tk.CENTER, height=2 , width=50 ,font=('楷体', 20),background='lightcyan') # 文本框名字
b.grid(row=0,columnspan=6)
输入框
输入框a1和a2使用Entry控件,前缀标签a和b使用Label控件。justify属性控制文字对齐方式(左或右);width和height分别定义宽度和高度;font属性指定字体(如楷体)及字号,若不设置则使用默认值。通过grid()方法确定行列位置,row和column指定具体行列,rowspan和columnspan指定跨越的行列数。使用.get()方法获取输入框内容。
b1=tk.Label(win, text='a:',justify=tk.CENTER, height=2 , width=5 ,font=('楷体', 15)) # 文本框名字
b1.grid(row=1,column=0)
a1 = tk.Entry(win, justify=tk.LEFT, width=15 , font=('楷体', 15)) # 文本框创建
a1.grid(row=1,column=1)
b2 = tk.Label(win, text='b:',justify=tk.CENTER, height=2 , width=5 , font=('楷体', 15)) # 文本框名字
b2.grid(row=2,column=0)
a2 = tk.Entry(win, justify=tk.LEFT, width=15 , font=('楷体', 15) ) # 文本框创建
a2.grid(row=2,column=1)
文本记录框
用于显示历史计算的文本区域。通过insert方法插入拼接好的字符串,利用数值标记实现换行。若未设置文本框大小而仅指定行列数,可能导致窗口大小不定且组件间空隙过大,影响美观。
txt = tk.Text(win,height=20, width=40 ,font=('楷体', 15)) #font对输入的文本的字体和大小进行规定
txt.grid(row=1,column=4,rowspan=4,columnspan=4) #大小是4*4按钮功能
当输入两个数据后,根据按钮点击执行相应计算并弹出结果。具体实现包括:
- 当输入为空时,弹窗提示错误,并允许用户重新输入;
- 处理除法运算的特殊情况,即除数不能为零,输入错误时给予提示;
- 计算完成后,将算式拼接并插入文本框;
- 弹窗显示计算结果;
- 清空输入框,准备下一次计算;
- 判断历史计算次数,动态调整算式插入位置。两列数据间需设置间隔。
各按钮设计方法相似,仅实现功能不同,格式基本一致,可通过研究一个函数类推其他功能。
num=0 #用来记录历史计算次数
def sum():
if a1.get()=='' or a2.get()=='':
return tkinter.messagebox.showinfo('消息提示', '输入不能为空')
global num
num += 1
a = float(a1.get()) #获取输入框内的内容,收集到的为字符型,需要进行转化
b = float(a2.get())
c = a + b
s = str('%d'%a + ' + '+'%d'%b + ' = ' + '%d'%c) #完成数据的拼接
if num%2==0:
s=s+ '\n' #第偶数个算式后面加上空格进行间隔
print(num)
else:
s=s+'\t' #第奇数个算式进行换行处理
txt.insert(tk.END,s)
tkinter.messagebox.showinfo('消息提示', '求商结果是:%d'%c)
a1.delete(0, tk.END) #清空输入框内的数据
a2.delete(0, tk.END)
def multiply():
if a1.get()=='' or a2.get()=='':
return tkinter.messagebox.showinfo('消息提示', '输入不能为空')
global num
num += 1
a = float(a1.get())
b = float(a2.get())
c = a * b
s = str('%d' % a + ' * ' + '%d' % b + ' = ' + '%d' % c)
if num%2==0:
s=s+ '\n'
print(num)
else:
s=s+'\t'
txt.insert(tk.END, s)
tkinter.messagebox.showinfo('消息提示', '求积结果是:%d'%c)
a1.delete(0, tk.END)
a2.delete(0, tk.END)
def subtract():
if a1.get()=='' or a2.get()=='':
return tkinter.messagebox.showinfo('消息提示', '输入不能为空')
global num
num += 1
a = float(a1.get())
b = float(a2.get())
c = a - b
s = str('%d' % a + ' - ' + '%d' % b + ' = ' + '%d' % c)
if num%2==0:
s=s+ '\n'
print(num)
else:
s=s+'\t'
txt.insert(tk.END, s)
tkinter.messagebox.showinfo('消息提示', '求差结果是:%d'%c)
a1.delete(0, tk.END)
a2.delete(0, tk.END)
def divide():
if a1.get()=='' or a2.get()=='':
return tkinter.messagebox.showinfo('消息提示', '输入不能为空')
global num
num += 1
a = float(a1.get())
b = float(a2.get())
if float(b)==0.0:
tkinter.messagebox.showinfo('消息提示', '除数不能为零!!!')
a2.delete(0 , tk.END) # 当除数为0时,不能进行计算,并且需要弹窗提示,清空数据
else:
c = a / b
s = str('%d' % a + ' / ' + '%d' % b + ' = ' + '%d' % c)
if num % 2 == 0:
s = s + '\n'
print(num)
else:
s = s + '\t'
txt.insert(tk.END, s)
tkinter.messagebox.showinfo('消息提示', '求商结果是:%d'%c)
a1.delete(0, tk.END)
a2.delete(0, tk.END)按钮
此处有一个常见陷阱:若直接编写command=sum(),函数会在程序启动时立即执行一次,导致运行初期即提示“输入不能为空”。经过多次尝试,发现需在函数前添加“lambda:”即可解决。justify=tk.CENTER用于设置按钮文字居中。
a4 = tk.Button(win, text='求和',justify=tk.CENTER, width=10, font=('楷体', 15) ,command = lambda :sum() ) # 文本框创建
a4.grid(row=3, column=0)
a5 = tk.Button(win, text='求积', justify=tk.CENTER, width=10 , font=('楷体', 15), command = lambda :multiply()) # 文本框创建
a5.grid(row=3, column=1)
a6 = tk.Button(win, text='求差', justify=tk.CENTER, width=10, font=('楷体', 15), command = lambda :subtract()) # 文本框创建
a6.grid(row=4, column=0)
a7 = tk.Button(win, text='求商', justify=tk.CENTER, width=10, font=('楷体', 15), command = lambda :divide()) # 文本框创建
a7.grid(row=4, column=1)
附完整代码:
import tkinter as tk
import tkinter.messagebox
win = tk.Tk() #窗口名称
win.title("简易计算器")
win.geometry('650x600') # 这里的乘是小x
b=tk.Label(win, text='简易计算器',justify=tk.CENTER, height=2 , width=50 ,font=('楷体', 20),background='lightcyan') # 文本框名字
b.grid(row=0,columnspan=6)
b1=tk.Label(win, text='a:',justify=tk.CENTER, height=2 , width=5 ,font=('楷体', 15)) # 文本框名字
b1.grid(row=1,column=0)
a1 = tk.Entry(win, justify=tk.LEFT, width=15 , font=('楷体', 15)) # 文本框创建
a1.grid(row=1,column=1)
b2 = tk.Label(win, text='b:',justify=tk.CENTER, height=2 , width=5 , font=('楷体', 15)) # 文本框名字
b2.grid(row=2,column=0)
a2 = tk.Entry(win, justify=tk.LEFT, width=15 , font=('楷体', 15) ) # 文本框创建
a2.grid(row=2,column=1)
txt = tk.Text(win,height=20, width=40 ,font=('楷体', 15))
txt.grid(row=1,column=4,rowspan=4,columnspan=4)
num=0
def sum():
if a1.get()=='' or a2.get()=='':
return tkinter.messagebox.showinfo('消息提示', '输入不能为空')
global num
num += 1
a = float(a1.get())
b = float(a2.get())
c = a + b
s = str('%d'%a + ' + '+'%d'%b + ' = ' + '%d'%c)
if num%2==0:
s=s+ '\n'
print(num)
else:
s=s+'\t'
txt.insert(tk.END,s)
tkinter.messagebox.showinfo('消息提示', '求商结果是:%d'%c)
a1.delete(0, tk.END)
a2.delete(0, tk.END)
def multiply():
if a1.get()=='' or a2.get()=='':
return tkinter.messagebox.showinfo('消息提示', '输入不能为空')
global num
num += 1
a = float(a1.get())
b = float(a2.get())
c = a * b
s = str('%d' % a + ' * ' + '%d' % b + ' = ' + '%d' % c)
if num%2==0:
s=s+ '\n'
print(num)
else:
s=s+'\t'
txt.insert(tk.END, s)
tkinter.messagebox.showinfo('消息提示', '求积结果是:%d'%c)
a1.delete(0, tk.END)
a2.delete(0, tk.END)
def subtract():
if a1.get()=='' or a2.get()=='':
return tkinter.messagebox.showinfo('消息提示', '输入不能为空')
global num
num += 1
a = float(a1.get())
b = float(a2.get())
c = a - b
s = str('%d' % a + ' - ' + '%d' % b + ' = ' + '%d' % c)
if num%2==0:
s=s+ '\n'
print(num)
else:
s=s+'\t'
txt.insert(tk.END, s)
tkinter.messagebox.showinfo('消息提示', '求差结果是:%d'%c)
a1.delete(0, tk.END)
a2.delete(0, tk.END)
def divide():
if a1.get()=='' or a2.get()=='':
return tkinter.messagebox.showinfo('消息提示', '输入不能为空')
global num
num += 1
a = float(a1.get())
b = float(a2.get())
if float(b)==0.0:
tkinter.messagebox.showinfo('消息提示', '除数不能为零!!!')
a2.delete(0 , tk.END) # 删除文本框内索引为0-999的字符
else:
c = a / b
s = str('%d' % a + ' / ' + '%d' % b + ' = ' + '%d' % c)
if num % 2 == 0:
s = s + '\n'
print(num)
else:
s = s + '\t'
txt.insert(tk.END, s)
tkinter.messagebox.showinfo('消息提示', '求商结果是:%d'%c)
a1.delete(0, tk.END)
a2.delete(0, tk.END)
a4 = tk.Button(win, text='求和',justify=tk.CENTER, width=10, font=('楷体', 15) ,command = lambda :sum() ) # 文本框创建
a4.grid(row=3, column=0)
a5 = tk.Button(win, text='求积', justify=tk.CENTER, width=10 , font=('楷体', 15), command = lambda :multiply()) # 文本框创建
a5.grid(row=3, column=1)
a6 = tk.Button(win, text='求差', justify=tk.CENTER, width=10, font=('楷体', 15), command = lambda :subtract()) # 文本框创建
a6.grid(row=4, column=0)
a7 = tk.Button(win, text='求商', justify=tk.CENTER, width=10, font=('楷体', 15), command = lambda :divide()) # 文本框创建
a7.grid(row=4, column=1)
win.mainloop()本篇博客仅实现了基础计算功能,后续可研究添加更多功能。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









