本文目录:
1、最终效果
2、GUI编写
3、回调函数说明
4、完整代码
---------------------------------------------------------------------/ 正文 /---------------------------------------------------------------------
1、最终效果图
如图所示,这个计算器要实现最普通的四则混合运算和带括号的计算
同时,我们可以自己设置小彩蛋或者表白语,如果你想来一个出其不意的表白或者吐槽,可以试试看哦
2、GUI编写
2.1 tkinter概述
- 本程序使用的模块是python自带的GUI模块 tkinter
- tkinter的各种参数介绍,可参考如下链接 https://www.cnblogs.com/aland-1415/p/6849193.html
- tkinter的视频教程请参见B站视频 https://www.bilibili.com/video/av8727878/
- GUI基本制作过程:编写出GUI界面控件或主窗口 ——放置编写好的控件或窗口 —— 编写事件(回调函数)
2.2 各部分编写过程
这个GUI很简单,主要可以分为三部分:
- 主窗口
- 用于显示算式与计算结果的Label(其实就是现实计算器的显示屏)
- 按钮
2.2.1 主窗口编写
import tkinter as TK
# 主窗口
root = TK.Tk( ) # 创建TK实例
root.title("King's Caculator") # 设置窗口的显示名字
root.resizable(0,0) # 设置主窗口的宽度和高度是否可以通过鼠标进行拉伸改变,此处设置为不能
root.geometry('320x420') # 这里设置主窗口的初始尺寸,因为我们在上面设定了主窗口大小 不可变,因此这个尺寸也就是主窗口一直不变的尺寸了
(# 此处继续编写其他GUI部分或者回调函数)
root.mainloop( ) # 在编写完所有的GUI与相关函数后,我们要让这个窗口不断的循环,做成一直显示的效果,如果没有这一行,主窗口会出现一瞬间然后消失,像是程序没有运行一样
2.2.2 用于显示算式与计算结果的Label
result = TK.StringVar( ) # 用来显示结果的可变文本
equation = TK.StringVar( ) # 用来显示算式的可变文本
result.set(' ') # 赋初始值
equation.set('0') # 赋初始值
# 结果显示框
show_uresult = TK.Label(root,bg='white',fg = 'black',font =('Arail','15'),bd='0',textvariable =equation,anchor='se')
show_dresult = TK.Label(root,bg='white',fg = 'black',font = ('Arail','30'),bd='0',textvariable=result,anchor='se')
show_uresult.place(x='10',y='10',width='300',height='50')
show_dresult.place(x='10',y='60',width='300',height='50')
这里我们使用的是tkinter模块15个主要控件里面的Label控件,然后在Lable上面显示文本
因为我们的文字是需要根据用户的输入随时发生改变,因此文字要使用StringVar变量,而不要使用普通的字符串
虽然显示效果上是一个Lable,但其实是两个Lable,这样子可以单独设置算式文本和结果文本的字体大小颜色等,以作区别,当然你也可以设置为一个大Lable,然后分别显示。
2.2.3 按钮
# 按钮
# 第一行按钮
button_back =TK.Button(root,text='←',bg='DarkGray',command=back)
button_back.place(x = '10',y='150',width = '60',height='40')
button_lbracket=TK.Button(root,text='(',bg='DarkGray',command= lambda : getnum('('))
button_lbracket.place(x = '90',y='150',width = '60',height='40')
button_rbracket=TK.Button(root,text=')',bg='DarkGray',command= lambda : getnum(')'))
button_rbracket.place(x = '170',y='150',width = '60',height='40')
button_division =TK.Button(root,text='÷',bg='DarkGray',command= lambda : getnum('÷'))
button_division.place(x = '250',y='150',width = '60',height='40')
# 第二行按钮
button_7 =TK.Button(root,text='7',bg='DarkGray',command= lambda : getnum('7'))
button_7.place(x = '10',y='205',width = '60',height='40')
button_8 =TK.Button(root,text='8',bg='DarkGray',command= lambda : getnum('8'))
button_8.place(x = '90',y='205',width = '60',height='40')
button_9 =TK.Button(root,text='9',bg='DarkGray',command= lambda : getnum('9'))
button_9.place(x = '170',y='205',width = '60',height='40')
button_multiplication =TK.Button(root,text='X',bg='DarkGray',command= lambda : getnum('x'))
button_multiplication.place(x = '250',y='205',width = '60',height='40')
# 第三行按钮
button_4 =TK.Button(root,text='4',bg='DarkGray',command= lambda : getnum('4'))
button_4.place(x = '10',y='260',width = '60',height='40')
button_5 =TK.Button(root,text='5',bg='DarkGray',command= lambda : getnum('5'))
button_5.place(x = '90',y='260',width = '60',height='40')
button_6 =TK.Button(root,text='6',bg='DarkGray',command= lambda : getnum('6'))
button_6.place(x = '170',y='260',width = '60',height='40')
button_minus =TK.Button(root,text='—',bg='DarkGray',command= lambda : getnum('-'))
button_minus.place(x = '250',y='260',width = '60',height='40')
# 第四行按钮
button_1 =TK.Button(root,text='1',bg='DarkGray',command= lambda :getnum('1'))
button_1.place(x = '10',y='315',width = '60',height='40')
button_2 =TK.Button(root,text='2',bg='DarkGray',command= lambda : getnum('2'))
button_2.place(x = '90',y='315',width = '60',height='40')
button_3 =TK.Button(root,text='3',bg='DarkGray',command= lambda : getnum('3'))
button_3.place(x = '170',y='315',width = '60',height='40')
button_plus =TK.Button(root,text='+',bg='DarkGray',command= lambda : getnum('+'))
button_plus.place(x = '250',y='315',width = '60',height='40')
# 第五行按钮
button_MC =TK.Button(root,text='MC',bg='DarkGray',command = clear)
button_MC.place(x = '10',y='370',width = '60',height='40')
button_0 =TK.Button(root,text='0',bg='DarkGray',command= lambda : getnum('0'))
button_0.place(x = '90',y='370',width = '60',height='40')
button_point =TK.Button(root,text='.',bg='DarkGray',command= lambda : getnum('.'))
button_point.place(x = '170',y='370',width = '60',height='40')
button_equal=TK.Button(root,text='=',bg='DarkGray',command= run)
button_equal.place(x = '250',y='370',width = '60',height='40')
注意按钮的command参数,这是回调函数,当这个按钮被按下时,回调函数被自动调用,用lambda函数是为了可以传参数给回调函数,否则无法传参。
3、回调函数说明
本程序的回调函数一共有4个
- 按下数字按钮或者四则运算按钮或括号按钮 getnum( )
- 按下退格按钮 def back( )
- 按下MC按钮 def clear( )
- 按下等号按钮 def run( )
3.1 按下数字按钮或者四则运算按钮或括号按钮 getnum( )
def getnum(num):
temp = equation.get( )
temp2 = result.get( )
print(temp)
print(temp2)
if temp2 != ' ' :
temp = '0'
temp2 = ' '
result.set(temp2)
if (temp=='0'):
temp = ''
temp = temp + num
equation.set( temp )
print(equation)
要考虑两个状态,状态一是结果文本为空,说明还没有进行过计算或者 按下了MC键,这时候输入什么都增加进算式文本,状态二是结果文本不为空, 说明刚进行完一次计算,要开始下一次计算,这时把算式文本和结果文本先初始化,或者再添加用户的新输入。(算式文本初始值是0,当用户输入第一个按钮时记得先把0去掉,否则会出现‘07+9’这类情况出现)
3.2 按下退格按钮 def back( )
# 按下退格键时,去除最后一个字符
def back( ):
temp = equation.get( )
equation.set(temp[:-1])
3.3 按下MC按钮 def clear( )
# 按下MC时,清空算式行与结果行
def clear( ):
equation.set('0')
result.set(' ')
3.4 按下等号按钮 def run( )
# 按下等于号时计算结果
def run( ):
temp = equation.get( )
temp = temp.replace('x','*') # 为了方便后续调用caculator函数进行运算,因此进行符号处理
temp = temp.replace('÷','/') # 为了方便后续调用caculator函数进行运算,因此进行符号处理
# 写一个小彩蛋,可以用于表白哦
if temp == '5+2+0+1+3+1+4': # 暗号
result.set('xxx我爱你') # 彩蛋或者表白语
return 0
print(temp)
answer = caculator.caculator(temp)
answer = '%.2f'%answer # 设定结果的小数点个数,可自定义
result.set(str(answer))
当按下等于号时,计算算式结果并显示出来
answer = caculator.caculator(temp)
这个函数请参见本人上一篇博客 https://blog.csdn.net/a971956955/article/details/81489914
或者直接使用python自带的 eval() 函数进行计算
4、完整代码
import tkinter as TK
#若调用 eval()函数进行计算结果,把下面这一小段代码去掉
#########################################################
import os,sys
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
sys.path.append(BASE_DIR)
from caculate import caculator
##########################################################
# 主窗口
root = TK.Tk( )
root.title("King's Caculator")
root.resizable(0,0)
root.geometry('320x420')
result = TK.StringVar( )
equation = TK.StringVar( )
result.set(' ')
equation.set('0')
# 获得按下的数字或者符号
def getnum(num):
temp = equation.get( )
temp2 = result.get( )
print(temp)
print(temp2)
if temp2 != ' ' :
temp = '0'
temp2 = ' '
result.set(temp2)
if (temp=='0'):
temp = ''
temp = temp + num
equation.set( temp )
print(equation)
# 按下退格键时,去除最后一个字符
def back( ):
temp = equation.get( )
equation.set(temp[:-1])
# 按下MC时,清空算式行与结果行
def clear( ):
equation.set('0')
result.set(' ')
# 按下等于号时计算结果
def run( ):
temp = equation.get( )
temp = temp.replace('x','*')
temp = temp.replace('÷','/')
# 写一个小彩蛋,可以用于表白哦
if temp == '5+2+0+1+3+1+4': # 暗号
result.set('xxx我爱你') # 彩蛋或者表白语
return 0
print(temp)
answer = caculator.caculator(temp)
answer = '%.2f'%answer
result.set(str(answer))
# 结果显示框
show_uresult = TK.Label(root,bg='white',fg = 'black',font = ('Arail','15'),bd='0',textvariable =equation,anchor='se')
show_dresult = TK.Label(root,bg='white',fg = 'black',font = ('Arail','30'),bd='0',textvariable=result,anchor='se')
show_uresult.place(x='10',y='10',width='300',height='50')
show_dresult.place(x='10',y='60',width='300',height='50')
# 按钮
# 第一行按钮
button_back =TK.Button(root,text='←',bg='DarkGray',command=back)
button_back.place(x = '10',y='150',width = '60',height='40')
button_lbracket=TK.Button(root,text='(',bg='DarkGray',command= lambda : getnum('('))
button_lbracket.place(x = '90',y='150',width = '60',height='40')
button_rbracket=TK.Button(root,text=')',bg='DarkGray',command= lambda : getnum(')'))
button_rbracket.place(x = '170',y='150',width = '60',height='40')
button_division =TK.Button(root,text='÷',bg='DarkGray',command= lambda : getnum('÷'))
button_division.place(x = '250',y='150',width = '60',height='40')
# 第二行按钮
button_7 =TK.Button(root,text='7',bg='DarkGray',command= lambda : getnum('7'))
button_7.place(x = '10',y='205',width = '60',height='40')
button_8 =TK.Button(root,text='8',bg='DarkGray',command= lambda : getnum('8'))
button_8.place(x = '90',y='205',width = '60',height='40')
button_9 =TK.Button(root,text='9',bg='DarkGray',command= lambda : getnum('9'))
button_9.place(x = '170',y='205',width = '60',height='40')
button_multiplication =TK.Button(root,text='X',bg='DarkGray',command= lambda : getnum('x'))
button_multiplication.place(x = '250',y='205',width = '60',height='40')
# 第三行按钮
button_4 =TK.Button(root,text='4',bg='DarkGray',command= lambda : getnum('4'))
button_4.place(x = '10',y='260',width = '60',height='40')
button_5 =TK.Button(root,text='5',bg='DarkGray',command= lambda : getnum('5'))
button_5.place(x = '90',y='260',width = '60',height='40')
button_6 =TK.Button(root,text='6',bg='DarkGray',command= lambda : getnum('6'))
button_6.place(x = '170',y='260',width = '60',height='40')
button_minus =TK.Button(root,text='—',bg='DarkGray',command= lambda : getnum('-'))
button_minus.place(x = '250',y='260',width = '60',height='40')
# 第四行按钮
button_1 =TK.Button(root,text='1',bg='DarkGray',command= lambda :getnum('1'))
button_1.place(x = '10',y='315',width = '60',height='40')
button_2 =TK.Button(root,text='2',bg='DarkGray',command= lambda : getnum('2'))
button_2.place(x = '90',y='315',width = '60',height='40')
button_3 =TK.Button(root,text='3',bg='DarkGray',command= lambda : getnum('3'))
button_3.place(x = '170',y='315',width = '60',height='40')
button_plus =TK.Button(root,text='+',bg='DarkGray',command= lambda : getnum('+'))
button_plus.place(x = '250',y='315',width = '60',height='40')
# 第五行按钮
button_MC =TK.Button(root,text='MC',bg='DarkGray',command = clear)
button_MC.place(x = '10',y='370',width = '60',height='40')
button_0 =TK.Button(root,text='0',bg='DarkGray',command= lambda : getnum('0'))
button_0.place(x = '90',y='370',width = '60',height='40')
button_point =TK.Button(root,text='.',bg='DarkGray',command= lambda : getnum('.'))
button_point.place(x = '170',y='370',width = '60',height='40')
button_equal=TK.Button(root,text='=',bg='DarkGray',command= run)
button_equal.place(x = '250',y='370',width = '60',height='40')
root.mainloop( )