Python实战---使用Tkinter构建计算器

目录

1  导入必要的模块

 2  创建主窗口并设置标题

3 加入计算器按钮

3.1 创建Entry小部件文本输入区域

3.2 使用grid布局管理器来定位和调整Entry小部件的大小。

3.3 创建按钮,并将其添加到GUI界面上

4 函数实现

 4.1 get_variables()函数实现

 4.2 get_operation()函数实现

4.3 calculate()函数实现

 4.3.1 获取输入

4.3.2 计算表达式

4.3.3 清除输入框

4.3.4 显示结果或错误

 4.4 clear_all()函数实现

4.5  undo()函数实现

4.5.1 获取输入框内容

4.5.2 检查输入框是否为空

4.5.3 撤销操作

4.5.4 显示错误信息

 4.6 fact()函数实现

 5 编译

6 拓展---打包为可执行文件

6.1 安装 PyInstaller

 6.2 进入.py文件目录

6.3 创建可执行文件

 6.4 找到并双击可执行文件

7 完整代码


计算器是我们日常生活中都会用到的一个应用程序。如果你正在学习python编程,Calculator是一个既简单又有用的项目。今天,我们将使用Tkinter构建一个Python计算器,步骤简单易懂。

Python提供了各种实用程序来设计GUI(图形用户界面),其中最常用的一个实用程序是Tkinter。它是构建GUI应用程序的最快和最简单的方法之一。此外,Tkinter是跨平台的,因此相同的代码可以在macOS, Windows和Linux上运行。

如下是计算器预览:

1  导入必要的模块

from tkinter import *
import ast
from math import factorial
  • tkinter:用于创建GUI应用程序。 
  • ast:用于安全地评估表达式。
  • factorial:计算阶乘的数学函数。

 2  创建主窗口并设置标题

root = Tk()
root.title('基于python tkinter的计算器')
root.mainloop()

如上代码为设置主窗口的标题,标题为“基于python tkinter的计算器” ,运行代码后窗口如下:

 

3 加入计算器按钮

#adding the input field
display = Entry(root)
display.grid(row=1,columnspan=6,sticky=N+E+W+S)
 
#Code to add buttons to the Calculator

Button(root,text="1",command = lambda :get_variables(1)).grid(row=2,column=0, sticky=N+S+E+W)
Button(root,text=" 2",command = lambda :get_variables(2)).grid(row=2,column=1, sticky=N+S+E+W)
Button(root,text=" 3",command = lambda :get_variables(3)).grid(row=2,column=2, sticky=N+S+E+W)
 
Button(root,text="4",command = lambda :get_variables(4)).grid(row=3,column=0, sticky=N+S+E+W)
Button(root,text=" 5",command = lambda :get_variables(5)).grid(row=3,column=1, sticky=N+S+E+W)
Button(root,text=" 6",command = lambda :get_variables(6)).grid(row=3,column=2, sticky=N+S+E+W)
 
Button(root,text="7",command = lambda :get_variables(7)).grid(row=4,column=0, sticky=N+S+E+W)
Button(root,text=" 8",command = lambda :get_variables(8)).grid(row=4,column=1, sticky=N+S+E+W)
Button(root,text=" 9",command = lambda :get_variables(9)).grid(row=4,column=2, sticky=N+S+E+W)
 
#adding other buttons to the calculator
Button(root,text="AC",command=lambda :clear_all()).grid(row=5,column=0, sticky=N+S+E+W)
Button(root,text=" 0",command = lambda :get_variables(0)).grid(row=5,column=1, sticky=N+S+E+W)
Button(root,text=" .",command=lambda :get_variables(".")).grid(row=5, column=2, sticky=N+S+E+W)
 
 
Button(root,text="+",command= lambda :get_operation("+")).grid(row=2,column=3, sticky=N+S+E+W)
Button(root,text="-",command= lambda :get_operation("-")).grid(row=3,column=3, sticky=N+S+E+W)
Button(root,text="*",command= lambda :get_operation("*")).grid(row=4,column=3, sticky=N+S+E+W)
Button(root,text="/",command= lambda :get_operation("/")).grid(row=5,column=3, sticky=N+S+E+W)
 
# adding new operations
Button(root,text="pi",command= lambda :get_operation("*3.14")).grid(row=2,column=4, sticky=N+S+E+W)
Button(root,text="%",command= lambda :get_operation("%")).grid(row=3,column=4, sticky=N+S+E+W)
Button(root,text="(",command= lambda :get_operation("(")).grid(row=4,column=4, sticky=N+S+E+W)
Button(root,text="exp",command= lambda :get_operation("**")).grid(row=5,column=4, sticky=N+S+E+W)
 
Button(root,text="<-",command= lambda :undo()).grid(row=2,column=5, sticky=N+S+E+W)
Button(root,text="x!", command= lambda: fact()).grid(row=3,column=5, sticky=N+S+E+W)
Button(root,text=")",command= lambda :get_operation(")")).grid(row=4,column=5, sticky=N+S+E+W)
Button(root,text="^2",command= lambda :get_operation("**2")).grid(row=5,column=5, sticky=N+S+E+W)
Button(root,text="^2",command= lambda :get_operation("**2")).grid(row=5,column=5, sticky=N+S+E+W)
Button(root,text="=",command= lambda :calculate()).grid(columnspan=6, sticky=N+S+E+W)

3.1 创建Entry小部件文本输入区域

Entry小部件通常用于让用户输入单行文本。这里的root是指主窗口对象。

3.2 使用grid布局管理器来定位和调整Entry小部件的大小。

  • row=1: 指定Entry小部件应放置在第1行。
  • columnspan=6: 表示Entry小部件应该跨越6列。这意味着它将占据从它的起始列开始的连续6列的空间。
  • sticky=N+E+W+S: 这个选项指定了小部件如何扩展以填充其单元格。这里的字母代表方向:
    • N: 北(顶部)
    • E: 东(右侧)
    • W: 西(左侧)
    • S: 南(底部)

 sticky=N+E+W+S 表示小部件将在所有四个方向上扩展,如果它所在的单元格允许的话。这意味着它将尽可能地扩展以填充整个单元格。

3.3 创建按钮,并将其添加到GUI界面上

创建Button小部件,包括数字、操作运算符,如按钮“1”,当按钮被点击时,它会调用一个匿名函数(lambda函数),该函数又调用get_variables函数(后文有函数实现),并传入参数1

4 函数实现

 4.1 get_variables()函数实现

数字0-9和小数点使用get_variables函数获取输入文本到输入文本框中,如下是函数实现:

#It keeps the track of current position on the input text field
i = 0
# Receives the digit as parameter and display it on the input field
def get_variables(num):
    global i
    display.insert(i,num)
    i+=1
  • i= 0:初始化变量 i 用于跟踪输入框中的光标位置
  • def get_variables(num):定义了一个名为 get_variables 的函数,接受一个参数 num
  • global i:声明了变量 i 是全局变量。在函数内部使用全局变量时,需要使用 global 关键字来表明你正在使用的是全局作用域中的变量
  • display.insert(i,num):插入文本到输入框,将参数 num 插入到GUI应用程序的输入框(Entry 小部件)中。display 是之前定义的 Entry 小部件的实例,insert 方法用于在指定位置插入文本。这里的 i 表示插入位置,num 是要插入的文本

 4.2 get_operation()函数实现

# Function which takes operator as input and displays it on the input field
def get_operation(operator):
    global i
    length = len(operator)
    display.insert(i,operator)
    i+=length

“+”、“-”、“*”、“/”、括号、平方等运算符使用get_operation函数来获取按钮文本,由于这些运算符长度不一,因此使用了len()函数来计算运算符长度,i+=length用来计算记录下一个字符或数字应该插入的位置。

4.3 calculate()函数实现

def calculate():
    entire_string = display.get()
    try:
        a = ast.parse(entire_string, mode="eval")
        result = eval(compile(a, "", mode="eval"))
        clear_all()
        display.insert(0,result)
    except Exception:
        clear_all()
        display.insert(0,"Error")

 4.3.1 获取输入

 display.get()获取了GUI应用程序中输入框(Entry 小部件)中的文本内容,并将其存储在变量 entire_string 中 

4.3.2 计算表达式

  • ast.parse(entire_string, mode="eval"): 这行代码使用Python的 ast 模块将字符串表达式转换为抽象语法树(Abstract Syntax Tree, AST)。mode="eval" 表示解析的目的只是为了评估表达式的值。
  • compile(a, "", mode="eval"): 使用 compile 函数将AST编译为可执行的代码对象。mode="eval" 表示编译后的代码将用于评估表达式的值。
  • eval(compile(a, "", mode="eval")): 使用 eval 函数来计算编译后的代码对象的值,并将结果存储在变量 result 中。

4.3.3 清除输入框

 调用了 clear_all()函数(后文有实现),用于清空输入框中的内容

4.3.4 显示结果或错误

 如果计算成功,将结果显示在输入框的最前面。

如果计算过程中发生异常(例如,输入的表达式无效或包含语法错误),则清除输入框的内容,并显示字符串 "Error"。

 4.4 clear_all()函数实现

#Function to clear the input field 
def clear_all():
    display.delete(0,END)

使用 delete 方法清空了 Entry 小部件中的内容。

  • 0: 表示从输入框的第一个字符开始删除。
  • END: 表示删除到输入框的末尾。

4.5  undo()函数实现

 undo()函数用于实现GUI应用程序中的撤销功能,即删除输入框(Entry 小部件)中的最后一个字符。代码如下:

#Function which works like backspace
def undo():
    entire_string = display.get()
    if len(entire_string):
        new_string = entire_string[:-1]
        clear_all()
        display.insert(0,new_string)
    else:
        clear_all()
        display.insert(0,"Error")

4.5.1 获取输入框内容

 entire_string = display.get():获取了GUI应用程序中输入框(Entry 小部件)中的文本内容,并将其存储在变量 entire_string

4.5.2 检查输入框是否为空

 if len(entire_string):检查输入框是否包含任何文本。如果输入框不为空(即 entire_string 的长度大于0),则执行撤销操作;否则,输入框为空,显示错误信息。 

4.5.3 撤销操作

 如果输入框不为空:

  • new_string = entire_string[:-1]: 创建一个新的字符串 new_string,包含 entire_string 中的所有字符,除了最后一个字符。
  • clear_all(): 调用 clear_all 函数来清空输入框的内容。
  • display.insert(0, new_string): 将新字符串 new_string 插入到输入框的开头位置。

4.5.4 显示错误信息

如果输入框为空,则执行以下操作:

  • clear_all(): 清空输入框的内容。
  • display.insert(0, "Error"): 将字符串 "Error" 插入到输入框的开头位置。

 4.6 fact()函数实现

fact()函数用于计算用户在GUI应用程序的输入框中输入的数字的阶乘,代码如下:

#Function to calculate the factorial and display it
def fact():
    entire_string = display.get()
    try:
        result = factorial(int(entire_string))
        clear_all()
        display.insert(0,result)
    except Exception:
        clear_all()
        display.insert(0,"Error")

 5 编译

 使用python解释器进行编译,编译指令如下:

D:/Anaconda/python.exe g:/learning/python/projects/calculator/dataflair-python-calculator/dataflair-python-calculator.py

注意替换自身电脑python解释器路径和.py文件路径。 

编译后输出如下计算器界面:

6 拓展---打包为可执行文件

6.1 安装 PyInstaller

pip install pyinstaller

 6.2 进入.py文件目录

cd G:\learning\python\projects\calculator\dataflair-python-calculator

注意如上路径替换为.py文件的实际路径。

6.3 创建可执行文件

pyinstaller --onefile your_script.py

其中 your_script.py 是您的 Python 脚本文件名。--onefile 参数告诉 PyInstaller 将所有依赖项合并到一个单独的可执行文件中。

 6.4 找到并双击可执行文件

可执行文件将位于 dist 目录下。可以将该目录下的文件复制到任何位置,并且可以在没有安装 Python解释器的情况下运行它。

 

 双击dataflair-python-calculator.exe可执行文件,运行界面如下:

7 完整代码

#Importing the necessary modules
from tkinter import *
# import parser
import ast
from math import factorial


root = Tk()
root.title('基于python tkinter的计算器')

#It keeps the track of current position on the input text field
i = 0
# Receives the digit as parameter and display it on the input field
def get_variables(num):
    global i
    display.insert(i,num)
    i+=1
 
# Calculate function scans the string to evaluates and display it
# def calculate():
#     entire_string = display.get()
#     try:
#         a = ast.parse(entire_string).compile()
#         result = eval(a)
#         clear_all()
#         display.insert(0,result)
#     except Exception:
#         clear_all()
#         display.insert(0,"Error")
def calculate():
    entire_string = display.get()
    try:
        a = ast.parse(entire_string, mode="eval")
        result = eval(compile(a, "", mode="eval"))
        clear_all()
        display.insert(0,result)
    except Exception:
        clear_all()
        display.insert(0,"Error")
 
# Function which takes operator as input and displays it on the input field
def get_operation(operator):
    global i
    length = len(operator)
    display.insert(i,operator)
    i+=length
 
#Function to clear the input field 
def clear_all():
    display.delete(0,END)
 
#Function which works like backspace
def undo():
    entire_string = display.get()
    if len(entire_string):
        new_string = entire_string[:-1]
        clear_all()
        display.insert(0,new_string)
    else:
        clear_all()
        display.insert(0,"Error")

#Function to calculate the factorial and display it
def fact():
    entire_string = display.get()
    try:
        result = factorial(int(entire_string))
        clear_all()
        display.insert(0,result)
    except Exception:
        clear_all()
        display.insert(0,"Error")

#--------------------------------------UI Design ---------------------------------------------

#adding the input field
display = Entry(root)
display.grid(row=1,columnspan=6,sticky=N+E+W+S)
 
#Code to add buttons to the Calculator

Button(root,text="1",command = lambda :get_variables(1)).grid(row=2,column=0, sticky=N+S+E+W)
Button(root,text=" 2",command = lambda :get_variables(2)).grid(row=2,column=1, sticky=N+S+E+W)
Button(root,text=" 3",command = lambda :get_variables(3)).grid(row=2,column=2, sticky=N+S+E+W)
 
Button(root,text="4",command = lambda :get_variables(4)).grid(row=3,column=0, sticky=N+S+E+W)
Button(root,text=" 5",command = lambda :get_variables(5)).grid(row=3,column=1, sticky=N+S+E+W)
Button(root,text=" 6",command = lambda :get_variables(6)).grid(row=3,column=2, sticky=N+S+E+W)
 
Button(root,text="7",command = lambda :get_variables(7)).grid(row=4,column=0, sticky=N+S+E+W)
Button(root,text=" 8",command = lambda :get_variables(8)).grid(row=4,column=1, sticky=N+S+E+W)
Button(root,text=" 9",command = lambda :get_variables(9)).grid(row=4,column=2, sticky=N+S+E+W)
 
#adding other buttons to the calculator
Button(root,text="AC",command=lambda :clear_all()).grid(row=5,column=0, sticky=N+S+E+W)
Button(root,text=" 0",command = lambda :get_variables(0)).grid(row=5,column=1, sticky=N+S+E+W)
Button(root,text=" .",command=lambda :get_variables(".")).grid(row=5, column=2, sticky=N+S+E+W)
 
 
Button(root,text="+",command= lambda :get_operation("+")).grid(row=2,column=3, sticky=N+S+E+W)
Button(root,text="-",command= lambda :get_operation("-")).grid(row=3,column=3, sticky=N+S+E+W)
Button(root,text="*",command= lambda :get_operation("*")).grid(row=4,column=3, sticky=N+S+E+W)
Button(root,text="/",command= lambda :get_operation("/")).grid(row=5,column=3, sticky=N+S+E+W)
 
# adding new operations
Button(root,text="pi",command= lambda :get_operation("*3.14")).grid(row=2,column=4, sticky=N+S+E+W)
Button(root,text="%",command= lambda :get_operation("%")).grid(row=3,column=4, sticky=N+S+E+W)
Button(root,text="(",command= lambda :get_operation("(")).grid(row=4,column=4, sticky=N+S+E+W)
Button(root,text="exp",command= lambda :get_operation("**")).grid(row=5,column=4, sticky=N+S+E+W)
 
Button(root,text="<-",command= lambda :undo()).grid(row=2,column=5, sticky=N+S+E+W)
Button(root,text="x!", command= lambda: fact()).grid(row=3,column=5, sticky=N+S+E+W)
Button(root,text=")",command= lambda :get_operation(")")).grid(row=4,column=5, sticky=N+S+E+W)
Button(root,text="^2",command= lambda :get_operation("**2")).grid(row=5,column=5, sticky=N+S+E+W)
Button(root,text="=",command= lambda :calculate()).grid(columnspan=6, sticky=N+S+E+W)

 
root.mainloop()

源码及打包后的可执行文件下载:https://download.csdn.net/download/sb2220/89665703

以上实战项目参考:https://data-flair.training/blogs/python-calculator-project/


END!!!

  • 23
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

codegrabber

如果觉得文章有用,请随意‘投喂

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值