欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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 系列,实现计算器基本加减乘除的运算


一、最终成果物

python tkinter 计算器V1.0

二、代码详解

1.基本框架

参考电脑自带的计算机,除去一些复杂的符号,只考虑简单的加减乘除,设计整体的框架如下:
python tkinter 计算器V1.0

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.内部逻辑

  1. 变量:
  • 标记位:标记上个按键是什么,
    isintbtn:标记按钮按的数字,默认未按
    isstrbtn :标记按钮按的符号,默认未按
    is_equal_last:标记上个按键是不是等号
  • 保存数据:
    list[]:保存整个计算过程中的按键;
    result1:记录显示板上面内容
    result2:记录显示板下面内容
  1. 按键逻辑
  • 1)按了数字后,如果前一个按键还是数字,组合在一起形成新的数字,并显示在下面显示板;
  • 2)按了符号,下面显示板不显示,保持原数字,但记录result2清空以便记录下个数字;且将之前的过程显示在上面显示板;
  • 3)按了等号后,将结果显示在下面显示板,过程显示在上面显示板;
  1. 特殊情况:
  • 连续按了多次“=”,将前一次等号计算的结果,与最后一次符号和数字重新计算,如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

总结

  1. 在设计过程中,会增加一些标记,如上个按键的情况,上个数字、符号,这些都是为了方便整合数字或处理特殊情况。在设计初期,就应该考虑除了正常的按键外,一些非正常的按键程序该如何响应(如连续按等号,等号后直接符号等)。
  2. 初始计算器已完成,对照电脑自带的计算器,还可增加更多符号(%、删除一位,清空按键等),来丰富计算器内容,敬请期待

本文地址:https://blog.csdn.net/u010234441/article/details/111992253