Python Tkinter实现简易桌面计算器

桃夭
桃夭
发布时间:2026-10-14| 4人浏览过
原创

本文介绍使用Python Tkinter库编写简易桌面计算器的完整实现。程序通过鼠标点击操作界面,数据持久化存储于指定文件,支持加减乘除、正负切换及清除功能。针对浮点数精度问题进行了说明,并提供了完整的源代码参考,适合Python初学者学习GUI编程与文件操作。

Python Tkinter计算器实现概述

本文分享一个使用Python编写的计算器程序,供读者参考学习。

界面展示与操作方式

计算器的界面设计如下所示:

数据存储与初始化机制

该程序基本实现了计算器的核心功能。需要注意的是,当前版本不支持键盘输入,仅能通过鼠标左键点击界面按钮来执行操作。程序启动时,显示框默认显示0.0,所有输入的数据会自动保存至D:\num.txt文件中(该文件在程序启动时若不存在则自动创建)。

核心功能按钮说明

功能按钮说明如下:点击“AC”按钮可清零并恢复初始值0.0;点击“delete”按钮可删除上一次输入的内容;点击“+/-”按钮可将当前数值在正数与负数之间切换。

关于不同进制数值系统下小数精度的差异,计算机可能会出现类似0.1+0.2=0.3000000000004的计算结果。虽然可以通过数据截断处理来规避此现象,但这会导致精度损失。本计算器未进行截断处理,因此保留了原始计算结果。

完整源代码实现


import tkinter,os
from tkinter import *

def temp(string):#空白间隔
  temp=tkinter.Frame(string,width=20,height=50)
  temp.pack()

flag=0
node=0
def num_work():   #更新显示框Lable
  global flag
  global node
  with open("D:\\num.txt") as f:
    for length in f:
      string=length
  top_work.configure(text=string.strip('\n'))  # 重新设置标签文本
  root.after(500,num_work) # 每隔0.5s调用函数num_work自身获取结果

def num_math_int(num1,num2):#整数运算
  try:
    if num2[0]=='+':
      string=int(num1)+int(num2[1:])
    elif num2[0]=='-':
      string=int(num1)-int(num2[1:])
    elif num2[0]=='x':
      string=int(num1)*int(num2[1:])
    elif num2[0]=='/':
      string=int(num1)/int(num2[1:])
      
    with open("D:\\num.txt",'a') as f:
      f.write('\n'+str(string)+'\n')
  except:
    with open("D:\\num.txt",'a') as f:
        f.write('\n错误')
def num_math_float(num1,num2):#小数运算
  try:
    if num2[0]=='+':
      string=float(num1)+float(num2[1:])
    elif num2[0]=='-':
      string=float(num1)-float(num2[1:])
    elif num2[0]=='x':
      string=float(num1)*float(num2[1:])
    elif num2[0]=='/':
      string=float(num1)/float(num2[1:])
    if flag==0:
      with open("D:\\num.txt",'a') as f:
        f.write('\n'+str(string)+'\n')
    else:
      with open("D:\\num.txt",'a') as f:
        f.write('\n'+str(string))
  except:
    with open("D:\\num.txt",'a') as f:
        f.write('\n错误')
def decimal(num):
  if num.count('%')>0:
    num=num.replace('%','')
    num=num.replace('\n','')
    if num.isnumeric():
      num=str(float(num)/100)
    else:
      num=num[0]+str(float(num[1:])/100)
  return num
    
def work(string):#按键对应的功能
  if string.isnumeric():
    with open("D:\\num.txt","a") as file:
      file.write(string)
  else:
    #读取文件D:\\num.txt所有内容
    lists=[]
    with open("D:\\num.txt","r") as file:
      for length in file:
        lists.append(length)
          
    if string=='AC':
      with open("D:\\num.txt","w") as file:
        file.write('0.0\n')
        
    elif string=='=':
      num1=lists[-2]
      num2=lists[-1]
      if num1=='\n':#解决末尾为换行的情况
        num1=lists[-3]
        
      #将百分数小数化
      #出现结果多0.0000000001
      num1=decimal(num1)
      num2=decimal(num2)
        
      try:      #判断两个数是整数还是小数
        number=int(num1)
        number=int(num2[1:])
        num_math_int(num1,num2)#两个数进行整数运算
      except:
        num_math_float(num1,num2)#两个数进行小数运算
        
    elif string=='.':
      if lists[-1].count('.')==0:#判断结尾是否有小数点,没有写入否则报错
        with open("D:\\num.txt","a") as file:
          file.write(string)
      else:
        with open("D:\\num.txt","a") as file:
          file.write('\n错误')
          
    elif string=='+/-':
      if lists[-1].count('-')==0:#-+为-
        if lists[-1].count('+')==1:
          lists[-1]=lists[-1].replace('+','')
        lists[-1]='-'+lists[-1]
      else:           #--为+
        lists[-1]=lists[-1].replace('-','+')
      #更新文件
      with open("D:\\num.txt","w") as file:
        pass
      for length in lists:
        with open("D:\\num.txt","a") as file:
          file.write(length)
          
    elif string=='delete':
      number=lists[-1]
      lists[-1]=number[0:(len(number)-1)]#删除一位
      #更新文件
      with open("D:\\num.txt","w") as file:
        pass
      for length in lists:
        with open("D:\\num.txt","a") as file:
          file.write(length)
    elif string=='%':
      if lists[-1].endswith("%")==False:
        with open("D:\\num.txt","a") as file:
          file.write(string)
      else:
        with open("D:\\num.txt","a") as file:
          file.write('\n错误')
      
    else:
      with open("D:\\num.txt","a") as file:
        file.write('\n'+string)
  
def run():#计算器显示界面主体
  
  if os.path.exists("D:\\num.txt")==False:
    with open("D:\\num.txt",'w') as f:
      f.write('0.0\n')
      
  global root#定义全局变量root,方便Label更新
  root=tkinter.Tk()
  root.title("计算器")
  
  #x = root.winfo_screenwidth()
  #获取当前屏幕的宽
  #y = root.winfo_screenheight()
  #获取当前屏幕的高
  #print(((x-500)//2),((y-600)//2))#为居中提供的参数
  
  root.geometry('400x500+760+290')#主体长400,高500,居中
  top=tkinter.Frame(root,width=20,height=50)
  top.pack()

  global top_work#定义全局变量root
  temp(top)#空白间隔
  #计算器显示框
  top_work=tkinter.Label(top,text='',justify='left',relief=SUNKEN,bd=10,bg='white',width=40)
  top_work.pack(side='bottom')#计算器显示框(位置居下)
  num_work()
  temp(root)#空白间隔
  
  number=tkinter.Frame(root)#成放计算机键盘的容器
  number.pack()
  #所有按键,AC键为事例
  numberAC=tkinter.Button(number,text="AC",width=10,command=lambda : work('AC')).grid(row=0,column=0)
  #左键点击,执行函数work
  #按键位置(0,0)
  
  numberdelete=tkinter.Button(number,text="delete",width=10,command=lambda : work('delete')).grid(row=0,column=1)
  numberzhengfu=tkinter.Button(number,text="+/-",width=10,command=lambda : work('+/-')).grid(row=0,column=2)
  numberchu=tkinter.Button(number,text="/",width=10,command=lambda : work('/')).grid(row=0,column=3)
  
  tkinter.Button(number,text="7",width=10,command=lambda : work('7')).grid(row=1,column=0)
  tkinter.Button(number,text="8",width=10,command=lambda : work('8')).grid(row=1,column=1)
  tkinter.Button(number,text="9",width=10,command=lambda : work('9')).grid(row=1,column=2)
  tkinter.Button(number,text="x",width=10,command=lambda : work('x')).grid(row=1,column=3)
  
  tkinter.Button(number,text="4",width=10,command=lambda : work('4')).grid(row=2,column=0)
  tkinter.Button(number,text="5",width=10,command=lambda : work('5')).grid(row=2,column=1)
  tkinter.Button(number,text="6",width=10,command=lambda : work('6')).grid(row=2,column=2)
  tkinter.Button(number,text="-",width=10,command=lambda : work('-')).grid(row=2,column=3)
  
  tkinter.Button(number,text="1",width=10,command=lambda : work('1')).grid(row=3,column=0)
  tkinter.Button(number,text="2",width=10,command=lambda : work('2')).grid(row=3,column=1)
  tkinter.Button(number,text="3",width=10,command=lambda : work('3')).grid(row=3,column=2)
  tkinter.Button(number,text="+",width=10,command=lambda : work('+')).grid(row=3,column=3)
  
  tkinter.Button(number,text="%",width=10,command=lambda : work('%')).grid(row=4,column=0)
  tkinter.Button(number,text="0",width=10,command=lambda : work('0')).grid(row=4,column=1)
  tkinter.Button(number,text=".",width=10,command=lambda : work('.')).grid(row=4,column=2)
  tkinter.Button(number,text="=",width=10,command=lambda : work('=')).grid(row=4,column=3)

  root.mainloop()
if __name__=='__main__':
  run()

浮点数精度问题说明

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。