python tkinter 计算器V1.0
程序员文章站
2022-11-17 10:48:34
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、最终成果物二、代码详解1.基本框架1.1 主窗口整体布局1.2 显示板1.3 按钮2.内部逻辑2.1 数字处理2.2 计算处理2.3 等号处理总结前言python tkinter 系列,实现计算器基本加减乘除的运算一、最终成果物二、代码详解1.基本框架参考电脑自带的计算机,除去一些复杂的符号,只考虑简单的加减乘除,设计整体的框架如下:1.1 主窗口整体布局1)主窗口固定大小,2)分为两部分,frm1...
前言
python tkinter 系列,实现计算器基本加减乘除的运算
一、最终成果物
二、代码详解
1.基本框架
参考电脑自带的计算机,除去一些复杂的符号,只考虑简单的加减乘除,设计整体的框架如下:
1.1 主窗口整体布局
1)主窗口固定大小,
2)分为两部分,frm1和frm2,frm1放置显示框,frm2放置按钮码如下:
import tkinter as tk
'''显示板显示输出,代码见1.2部分'''
def printout(result1, result2,frm):
'''按钮显示输出,代码见1.3部分'''
def layout_button(frm):
'''整体布局'''
def layout(root, result1, result2):
frm1 = tk.Frame(root) #frm1显示板框体
frm1.config(width=320, height=100, relief='solid', highlightthickness=2, highlightbackground='red')
printout(result1, result2, frm1)
frm1.grid(row=0, column=0)
frm1.grid_propagate(0) #固定大小不变
frm2 = tk.Frame(root) #frm2按键板框体
frm2.config(width=320, height=400, bg='#dfe9f4', relief='solid', highlightthickness=2, highlightbackground='blue')
layout_button(frm2)
frm2.grid(row=1, column=0)
frm2.grid_propagate(0)
root = tk.Tk()
root.title("计算器1.0")
root['bg'] = '#dfe9f4'
root.geometry("320x500")
result1 = tk.StringVar()
result1.set('') #上面显示板,默认显示空
result2 = tk.StringVar()
result2.set(0) #下面显示板,默认显示0
root.mainloop()
1.2 显示板
新建两个字符变量result1和result2,前者记录上层显示内容,后者记录下层显示内容
'''显示板显示输出'''
def printout(result1, result2,frm):
label1 = tk.Label(frm, font=('微软雅黑', 20), bg='#EEE9E9', bd='9', fg='#828282', anchor='se', textvariable=result1)
label1.place(relx=1, rely=0.5, relwidth=1, relheight=0.5, anchor='se')
label2 = tk.Label(frm, font=('微软雅黑', 20), bg='#EEE9E9', bd='9', fg='#828282', anchor='se', textvariable=result2)
label2.place(relx=1, rely=1, relwidth=1, relheight=0.5, anchor='se') #注意放置位置为东南角
1.3 按钮
按键布局位置,参考基本框架部分,布局采用place函数,位置为相对frm2的相位位置(relx,rely)。
数据按键对应数字处理函数press_num(),加减乘除对应计算函数press_compute(),等号对应单独计算结果函数press_equal()。
def layout_button(frm):
btn7 = tk.Button(frm, text='7', font=('微软雅黑', 20), bg='#f1f5fa', command=lambda:press_num('7'))
btn7.place(relx=0.125, rely=0.125, relwidth=0.23,relheight=0.23,anchor='center')
btn8 = tk.Button(frm, text='8', font=('微软雅黑', 20), bg='#f1f5fa', command=lambda:press_num('8'))
btn8.place(relx=0.375, rely=0.125, relwidth=0.23,relheight=0.23,anchor='center')
btn9 = tk.Button(frm, text='9', font=('微软雅黑', 20), bg='#f1f5fa', command=lambda:press_num('9'))
btn9.place(relx=0.625, rely=0.125, relwidth=0.23,relheight=0.23,anchor='center')
btn4 = tk.Button(frm, text='4', font=('微软雅黑', 20), bg='#f1f5fa', command=lambda:press_num('4'))
btn4.place(relx=0.125, rely=0.375, relwidth=0.23,relheight=0.23,anchor='center')
btn5 = tk.Button(frm, text='5', font=('微软雅黑', 20), bg='#f1f5fa', command=lambda:press_num('5'))
btn5.place(relx=0.375, rely=0.375, relwidth=0.23,relheight=0.23,anchor='center')
btn6 = tk.Button(frm, text='6', font=('微软雅黑', 20), bg='#f1f5fa', command=lambda:press_num('6'))
btn6.place(relx=0.625, rely=0.375, relwidth=0.23,relheight=0.23,anchor='center')
btn1 = tk.Button(frm, text='1', font=('微软雅黑', 20), bg='#f1f5fa', command=lambda:press_num('1'))
btn1.place(relx=0.125, rely=0.625, relwidth=0.23,relheight=0.23,anchor='center')
btn2 = tk.Button(frm, text='2', font=('微软雅黑', 20), bg='#f1f5fa', command=lambda:press_num('2'))
btn2.place(relx=0.375, rely=0.625, relwidth=0.23,relheight=0.23,anchor='center')
btn3 = tk.Button(frm, text='3', font=('微软雅黑', 20), bg='#f1f5fa', command=lambda:press_num('3'))
btn3.place(relx=0.625, rely=0.625, relwidth=0.23,relheight=0.23,anchor='center')
btn10 = tk.Button(frm, text='0', font=('微软雅黑', 20), bg='#f1f5fa', command=lambda:press_num('0'))
btn10.place(relx=0.125, rely=0.875, relwidth=0.23, relheight=0.23, anchor='center')
btn11= tk.Button(frm, text='.', font=('微软雅黑', 20), bg='#f1f5fa', command=lambda:press_num('.'))
btn11.place(relx=0.375, rely=0.875, relwidth=0.23,relheight=0.23,anchor='center')
btn12= tk.Button(frm, text='=', font=('微软雅黑', 20), bg='#f1f5fa', command=lambda:press_equal())
btn12.place(relx=0.625, rely=0.875, relwidth=0.23,relheight=0.23,anchor='center')
btn13= tk.Button(frm, text='+', font=('微软雅黑', 20), bg='#f1f5fa', command=lambda:press_compute('+'))
btn13.place(relx=0.875, rely=0.125, relwidth=0.23,relheight=0.23,anchor='center')
btn13 = tk.Button(frm, text='-', font=('微软雅黑', 20), bg='#f1f5fa', command=lambda:press_compute('-'))
btn13.place(relx=0.875, rely=0.375, relwidth=0.23, relheight=0.23, anchor='center')
btn13 = tk.Button(frm, text='X', font=('微软雅黑', 20), bg='#f1f5fa', command=lambda:press_compute('*'))
btn13.place(relx=0.875, rely=0.625, relwidth=0.23, relheight=0.23, anchor='center')
btn13 = tk.Button(frm, text='÷', font=('微软雅黑', 20), bg='#f1f5fa', command=lambda:press_compute('/'))
btn13.place(relx=0.875, rely=0.875, relwidth=0.23, relheight=0.23, anchor='center')
2.内部逻辑
- 变量:
- 标记位:标记上个按键是什么,
isintbtn:标记按钮按的数字,默认未按
isstrbtn :标记按钮按的符号,默认未按
is_equal_last:标记上个按键是不是等号 - 保存数据:
list[]:保存整个计算过程中的按键;
result1:记录显示板上面内容
result2:记录显示板下面内容
- 按键逻辑
- 1)按了数字后,如果前一个按键还是数字,组合在一起形成新的数字,并显示在下面显示板;
- 2)按了符号,下面显示板不显示,保持原数字,但记录result2清空以便记录下个数字;且将之前的过程显示在上面显示板;
- 3)按了等号后,将结果显示在下面显示板,过程显示在上面显示板;
- 特殊情况:
- 连续按了多次“=”,将前一次等号计算的结果,与最后一次符号和数字重新计算,如5+6,按“=”计算为11,再次按“=”后,计算变为11+6,结果为17。
- “=”计算出结果,直接按了符号,将结果作为初始的数值计算。
2.1 数字处理
逻辑:如果上次按的按钮是符号或等号,则将result2记为0,重新记数字;如果按的是数字,则在原来的基础上再把新按数字记上;
def press_num(num):
global isintbtn #标记按钮按的数字,默认未按
global isstrbtn #标记按钮按的符号,默认未按
global is_equal_last #标记上一个按键
global last_num #记录上一个数字
global list
if isstrbtn == False:
pass
else:
result2.set(0)
isstrbtn=False #若上次按键为符号,数字重新清零开始计数
if is_equal_last == True:
result2.set(0) #等号同理
oldnum = result2.get()
if oldnum == '0':
result2.set(num)
last_num = num
else:
newnum = oldnum+num
result2.set(newnum)
last_num = newnum #连续按数字,将数字连起来作为新的数字
is_equal_last = False #标记下上个按键已不是等号
2.2 计算处理
按了符号后,需将之前输入的数字和符号显示到上部分显示板上,同时把之前的数字和符号记录到list表中。
def press_compute(sign):
global isintbtn
global isstrbtn
global is_equal_last
global last_cpt
global list
num = result2.get()
list.append(num) #把数字记录到列表中
list.append(sign)
isstrbtn = True #把符号记录到列表中
is_equal_last = False
last_cpt = sign
cur_out = ''.join(list)
result1.set(cur_out) #上部分显示板显示之前输入的数字
2.3 等号处理
等号注意,如果正常数字结束的,根据list内容计算出结果,如果是连续按的等号,将list内容更新下,更换为结果+最后一个符号+最后一个数字,再计算结果。
def press_equal():
global isintbtn
global isstrbtn
global is_equal_last
global last_num
global list
if is_equal_last == False:
curnum = result2.get()
list.append(curnum)
computeStr = ''.join(list)
endnum = eval(computeStr) #使用eval函数将list内容计算出结果
result2.set(endnum)
result1.set(computeStr) #将计算结果和内容显示在显示板上
is_equal_last = True #标记此时最后一个按键是等号
list.clear() #清空list
else:
curnum = result2.get() #如果上次按键是等号,记录上次的计算结果
list.append(curnum)
list.append(last_cpt)
list.append(str(last_num)) #将计算结果、最后一次的符号、最后一个数字添加到list中
#print(list)
computeStr = ''.join(list)
endnum = eval(computeStr)
#print(computeStr)
result2.set(endnum)
result1.set(computeStr)
is_equal_last = True
list.clear() #按照新的list计算结果并显示
3、整体代码和最终结果
见下一篇:https://blog.csdn.net/u010234441/article/details/111995477
总结
- 在设计过程中,会增加一些标记,如上个按键的情况,上个数字、符号,这些都是为了方便整合数字或处理特殊情况。在设计初期,就应该考虑除了正常的按键外,一些非正常的按键程序该如何响应(如连续按等号,等号后直接符号等)。
- 初始计算器已完成,对照电脑自带的计算器,还可增加更多符号(%、删除一位,清空按键等),来丰富计算器内容,敬请期待
本文地址:https://blog.csdn.net/u010234441/article/details/111992253