一个完整简单而又强力的计算器程序--用python实现(Python3.7)

tech2022-07-12  182

注释都在文中写好了,十分详细,不多解释直接上代码

先让大家看看效果如何,具体操作还有各种用法,可以参考help里面的选项卡,file菜单中可以实现一些简单的操作,换算菜单中也内置了一些操作。

时间仓促,没能内置很多模块,不过可扩展性强,实现简单,大家可以自己动手来实现一些自己想要的功能。

大家可以去查看我博客里面的下载内容,有关于这个计算机程序的

源码64位应用程序32位应用程序

大家可以参考下载使用,注意:我Python的版本是3.7,要使用2.7版本的Python来编码的话,可能会有问题。

#计算器,刘元昊,郑倩霞,张美 #第一部分——导入库和库函数 import os import re import tkinter as tk import random import tkinter.messagebox from math import * #第二部分——对窗口、文本框的设置 #建新窗口—根窗口 root = tkinter.Tk() #设置窗口的大小和位置 root.geometry("300x490+400+200") #不允许改变高,不允许改变宽,0或False均可 root.resizable(0,False) #设置窗口标题 root.title("计算器——刘元昊,郑倩霞,张美") #在根窗口中建新一个以contentVar为控制变量的文本框,类型为可变文本框 contentVar = tkinter.StringVar(root,"") # tkinter中,Entry表示单行文本框,Text表示多行文本框 # 用textvariable设置为可变文本,与StringVar可变文本框等配合使用 contentEntry = tkinter.Entry(root,textvariable = contentVar) #将文本框状态设置为正常,即允许在文本框中进行键盘输入 contentEntry["state"] = "normal" #设置文本框的位置,宽度和高度 contentEntry.place(x=10,y=10,width=280,height=20) #第三部分——放置菜单和按钮 #(1)第一小部分放置按钮 #放置清除按钮和等号按钮,帮助与退出按钮 #传递给command属性的是函数对象,函数名后不能加括号,而这样定义的函数不能传递参数, #而执行相应的操作,需要对不同参数进行处理,故需要重新定义一个函数,让这个函数调用另一个函数 #lambda是一种快速定义的最小函数(单行) #注意:lambda 函数可以接收任意多个参数 (包括可选参数),并且返回单个表达式的值。 #lambda 函数不能包含命令,包含的表达式不能超过一个。 btnClear = tkinter.Button(root,text="Clear",command=lambda:buttonClick("Clear")) btnClear.place(x=20,y=40,width=50,height=20) btnDel = tkinter.Button(root,text="Del",command=lambda:buttonClick("Del")) btnDel.place(x=90,y=40,width=50,height=20) btnCompute = tkinter.Button(root,text="=",command=lambda:buttonClick("=")) btnCompute.place(x=230,y=40,width=50,height=20) btnHelp = tkinter.Button(root,text="帮助",command=lambda:buttonClick("帮助")) btnHelp.place(x=230,y=350,width=50,height=50) btnQuit = tkinter.Button(root,text="退出",command=lambda:quit()) btnQuit.place(x=230,y=430,width=50,height=20) #放置()[]按钮 signs = ["(",")","[","]"] number = 0 for sign in signs: number += 1 btnDigist = tkinter.Button(root,text=sign,command=lambda x=sign:buttonClick(x)) btnDigist.place(x=155+15*number,y=40,width=14,height=20) #放置0123456789十个数字,小数点,计算平方根,调用三角反三角函数以及随机数和历史的按钮 digists = list("0123456789.") + ["Sqrt","sin(","cos(","tanx(","asin(","acos(", "atan(","ceil(","floor(","abs(",",","随机数","历史"] index = 0 for row in range(8): for col in range(3): d = digists[index] index += 1 btnDigist = tkinter.Button(root,text=d,command=lambda x=d:buttonClick(x)) btnDigist.place(x=20 + col*70,y=80 + row*50,width = 50,height = 20) #放置运算符按钮和π,e以及数学常数τ的近似值按钮 operators = ("+","-","*","/","**","//","pi","e","tau") for index,operator in enumerate(operators): btnOperator = tkinter.Button(root,text=operator,command=lambda x=operator:buttonClick(x)) btnOperator.place(x=230,y=80+index*30,width=50,height=20) #(2)第二小部分放置菜单 m = tkinter.Menu(root) root.config(menu=m) #设置file选项 filemenu = tkinter.Menu(m) m.add_cascade(label="File",menu=filemenu) filemenu.add_command(label="New",command = lambda: callback("New")) filemenu.add_separator() filemenu.add_command(label="History",command=lambda:callback("History")) filemenu.add_separator() filemenu.add_command(label="Exit",command=lambda:quit()) filemenu.add_separator() filemenu.add_command(label="top",command=lambda:root.wm_attributes("-topmost",1)) filemenu.add_separator() #设置help选项 helpmenu = tkinter.Menu(m) m.add_cascade(label="Help",menu=helpmenu) list=['pi','e','tau','asin','//','**',"sqrt","随机数"] list_explain=["pi:圆周率π的近似值","e:自然对数e的近似值",'tau:数学常数τ的近似值', """asin,acos,atan,分别代表反三角函数: arcsin,arccos,arctan""","/:表示除号,//:表示整除","*:表示乘号,**:表示乘方", "Sqrt:表示开方","随机数:random.randint(x,y),将生成一个在区间[x,y]之间的随机整数"] index=0 help_dict={} for i in list: helpmenu.add_command(label=i,command=lambda x=i:callback(x)) help_dict[i]=list_explain[index] index += 1 #设置换算选项# changemenu=tkinter.Menu(m) m.add_cascade(label="换算",menu=changemenu) changemenu.add_command(label="BMI",command=lambda:callback("BMI")) changemenu.add_separator() changemenu.add_command(label="三维向量",command=lambda:callback("三维向量")) changemenu.add_separator() changemenu.add_command(label="信息1802抽签",command=lambda:callback("信息1802抽签")) #第四部分——按钮处理代码和菜单处理代码 #(1)第一小部分按钮处理代码 def buttonClick(btn): #获取录入框中的文本内容 content = contentVar.get() #根据不同的按钮,做出相应的处理 #如果已有内容时以小数点开头的,前面加0 if content.startswith("."): content = "0" + content + btn #如果参数为Clear,清空文本框,如果参数为Del,去除最后一个字符 elif btn == "Clear": content = "" elif btn == "Del": content = content[:-1] #如果新输入字符串btn是小数点,且字符串content的个数大于1并以运算符结尾时, #在小数点前加0,以数字结尾时,添加小数点,以ieu,结尾时报错,不对文本框内容做修改 elif btn == "." and len(content) >= 1: if content[-1] in "()[]+-*/": content = content + "0." elif content[-1] in "0123456789": content += btn elif content[-1] in "ieu,": tkinter.messagebox.showerror("错误:","π,eτ后不能有小数点") return #如果参数在"0123456789,()[]sin(cos(tan(pietauasin(acos(atan(ceil(floor(abs("之中, #在文本框末尾直接加入此参数 elif btn in "0123456789,()[]sin(cos(tan(pietauasin(acos(atan(ceil(floor(abs(": content += btn #如果参数为帮助,则弹出帮助提示界面,内含相关按钮介绍及使用方法 elif btn == "帮助": tkinter.messagebox.showinfo("帮助",""" pi:圆周率π的近似值 e:自然对数e的近似值 tau:数学常数τ的近似值 asin,acos,atan,分别代表反三角函数: arcsin,arccos,arctan /:表示除号 //:表示整除 *:表示乘号 **:表示乘方 Sqrt:表示开方 Clear:表示清空数据 del:表示退格,相当于电脑上的Backsace键 随机数:random.randint(x,y),将生成一个在区间[x,y]之间的随机整数 其他问题以及改进意见,请加QQ:273983336""") elif btn == "历史": pdw = os.getcwd() infile = open(pdw + "\\history.txt","r") text = infile.read() infile.close() tkinter.messagebox.showinfo("历史",text) return elif btn=="随机数": content += "random.randint(" elif btn == "=": try: #对输入的表达式求值,并写入文件 #获取当前文件所在的路径 pdw = os.getcwd() outfile = open(pdw + "\\history.txt","a") outfile.write(content) content = str(round(eval(content),10)) outfile.write("=" + content + "\n") outfile.close() except: tkinter.messagebox.showerror("错误","表达式错误") return elif btn in operators: if content.endswith(operators): tkinter.messagebox.showerror("错误","不允许连续运算符") return content += btn #如果参数为Sqrt,则 elif btn == "Sqrt": try: content = eval(content) ** 0.5 except: tkinter.messagebox.showerror("错误","表达式错误") contentVar.set(content) #(2)第二小部分菜单处理代码 def callback(btn): content = contentVar.get() if btn == "New": content = "" elif btn == "History": pdw = os.getcwd() infile = open(pdw + "\\history.txt","r") text = infile.read() infile.close() tkinter.messagebox.showinfo("历史",text) return elif btn in list: tkinter.messagebox.showinfo("Help",help_dict[btn]) return elif btn == "BMI": window_BMI=tk.Toplevel(root) window_BMI.geometry("350x200") window_BMI.title("这是一个计算BMI的程序") height=tk.StringVar() tk.Label(window_BMI,text="请输入身高(米):").place(x=10,y=10) tk.Entry(window_BMI,textvariable=height).place(x=150,y=10) weight=tk.StringVar() tk.Label(window_BMI,text="请输入体重(千克):").place(x=10,y=50) tk.Entry(window_BMI,textvariable=weight).place(x=150,y=50) btnBMI = tk.Button(window_BMI,text="计算",command=lambda:BMI()) btnBMI.place(x=10,y=90,height=30,width=50) out_BMI=tk.StringVar() tk.Label(window_BMI,text="BMI指数:").place(x=10,y=130) tk.Entry(window_BMI,textvariable=out_BMI).place(x=150,y=130) out_standard=tk.StringVar() tk.Label(window_BMI,text="指标水平:").place(x=10,y=170) tk.Entry(window_BMI,textvariable=out_standard).place(x=150,y=170) def BMI(): new_height=float(height.get()) new_weight=float(weight.get()) BMI = round(new_weight / new_height ** 2 ,2) out_BMI.set(BMI) if BMI >= 18.5 and BMI <= 23.9: out_standard.set("健康") else: out_standard.set("非正常") elif btn == "三维向量": window_vector=tk.Toplevel(root) window_vector.geometry("350x400") window_vector.title("三维向量的运算") vector1=tk.StringVar() tk.Label(window_vector,text="请输入向量v=(x,y,z)形如x,y,z,逗号为英文输入法下的逗号").place(x=10,y=10) tk.Label(window_vector,text="V1=").place(x=20,y=40) tk.Entry(window_vector,textvariable=vector1).place(x=100,y=40) vector2=tk.StringVar() tk.Label(window_vector,text="V2=").place(x=20,y=80) tk.Entry(window_vector,textvariable=vector2).place(x=100,y=80) btnvector=tk.Button(window_vector,text="计算",command=lambda:vector()) btnvector.place(x=10,y=120,height=30,width=50) #定义一个三维向量的类(重载运算符) #让类拦截常规的Python运算,重载是通过特殊名称的类方法来实现的 #运算符重载只是意味着在类方法中拦截内置的操作—— #当类的实例出现在内置操作中,Python自动调用你的方法, #并且你的方法的返回值变成了相应操作的结果。 class Vector3: def __init__(self,x,y,z): self.x=x self.y=y self.z=z #重载 +,-,*,** def __add__(self,obj): return Vector3(self.x + obj.x,self.y + obj.y,self.z + obj.z) def __sub__(self,obj): return Vector3(self.x - obj.x,self.y - obj.y,self.z - obj.z) def __mul__(self,obj): return Vector3(self.x * obj.x,self.y * obj.y,self.z * obj.z) def __str__(self): return str(self.x) + "," + str(self.y) + "," + str(self.z) # 向量的外积,(x1,y1,z1) x (x2,y2,z2)=(y1z2 - y2z1,z1x2-z2x1,x1y2-x2y1) def __pow__(self,obj): return Vector3(self.y*obj.z - obj.y*self.z, self.z*obj.x - obj.z*self.x,self.x*obj.y - obj.x*self.y) def vector(): v1=vector1.get() v2=vector2.get() l=re.split(",",v1)+re.split(",",v2) print(l) x,y,z,m,n,l=int(l[0]),int(l[1]),int(l[2]),int(l[3]),int(l[4]),int(l[5]) V1=Vector3(x,y,z) V2=Vector3(m,n,l) out_add=tk.StringVar() tk.Label(window_vector,text=" v1 + v2 = ").place(x=10,y=180) tk.Entry(window_vector,textvariable=out_add).place(x=100,y=180) out_add.set(V1+V2) out_sub=tk.StringVar() tk.Label(window_vector,text=" v1 - v2 = ").place(x=10,y=240) tk.Entry(window_vector,textvariable=out_sub).place(x=100,y=240) out_sub.set(V1-V2) out_mul=tk.StringVar() tk.Label(window_vector,text="内积:v1.v2=").place(x=10,y=300) tk.Entry(window_vector,textvariable=out_mul).place(x=100,y=300) out_mul.set(V1*V2) out_pow=tk.StringVar() tk.Label(window_vector,text="外积:v1Xv2=").place(x=10,y=350) tk.Entry(window_vector,textvariable=out_pow).place(x=100,y=350) out_pow.set(V1**V2) elif btn == "信息1802抽签": window_select = tk.Toplevel(root) window_select.geometry("350x400") window_select.title("信息1802抽签") get_number = tk.StringVar() tk.Label(window_select,text="请输入人数").place(x=10,y=10) tk.Entry(window_select,textvariable=get_number).place(x=100,y=40) lists=['钟锴\n', '李炯熠\n', '范小山\n', '栾福乔\n', '覃一耕\n', '王昭光\n', '刘元昊\n', '田浩江\n', '岳书豪\n', '赵展铭\n', '田昊伦\n', '贺言\n', '李子涵\n', '王欣\n', '李壮壮\n', '杨雨轩\n', '刘源\n', '王蕴达\n', '周子涵\n', '杨一磊\n', '涂志龙\n', '蔡舒妃\n', '张可怡\n', '胡芷莹\n', '韦洁媚\n', '贾玮\n', '许芷榕\n', '李瑞琪\n', '廖宁宁\n', '刘少聪\n', '杨思远\n', '成明珠\n'] btnnumber = tk.Button(window_select,text="抽取",command=lambda:what_number()) btnnumber.place(x=10,y=120,height=30,width=50) def what_number(): content='' number=int(get_number.get()) for i in range(1,number+1): x=random.randint(1,len(lists))-1 content += lists[x] + " " out_numbers=tk.StringVar() tk.Entry(window_select,textvariable=out_numbers).place(x=10,y=250,width=280,height=20) out_numbers.set(content) contentVar.set(content) #第五部分——进入主循环 #进入主(消息)循环,准备处理事件(必须组建),除非用户关闭窗口(或者按退出键), #否则程序将一直处于主循环中 #注意:只有进入了主循环,根窗口才可见 root.mainloop()
最新回复(0)