python tkinter简易计算器

Python tkinter简易计算器实现

emm,前人的代码让我受益匪浅,那么也希望我的作品能帮助到你们吧。废话不多说,直接上代码。

import tkinter as tk
from tkinter import messagebox, colorchooser, simpledialog
from decimal import *

#初始化主界面
def screen(root):
    root.geometry("220x270")
    root["bg"] = "white"

#菜单栏函数
def help_info():
    tk.messagebox.showinfo("帮助", "有问题请直接发邮件到2804578334@qq.com, 竭诚为你服务。")
def digit_set():
    i = tk.simpledialog.askinteger(title = "请输入保留位数", prompt = "请输入整数")
    calculator.re_dg = int(i)

def color():
    c = tk.colorchooser.askcolor()
    calculator["bg"] = c[1]
    root["bg"] = c[1]

#设置菜单
def main_menu():
    menubar = tk.Menu(root)
    
    menu_setting = tk.Menu(menubar)
    menubar.add_cascade(label = "settings", menu = menu_setting)
    menu_setting.add_command(label = "color", command = color)
    menu_other = tk.Menu(menu_setting)
    menu_setting.add_cascade(label = "other", menu = menu_other)
    menu_other.add_command(label = "reserve_digit", command = digit_set)
    
    menubar.add_command(label = "help", command = help_info)

    root["menu"] = menubar   

class Calculator(tk.Frame):
    def __init__(self, master = None):
        tk.Frame.__init__(self,master)
        self.pack()
        self.set_all()
        self.status = "input"
        self.re_dg = 10
        self["bg"] = "white"
    
    def set_all(self):
        self.v1 = tk.StringVar()
        self.pre_input = tk.Entry(self, textvariable = self.v1)
        self.pre_input.grid(row = 0, column = 0, columnspan = 8, padx = 3, pady = 5)
        self.v2 = tk.StringVar()
        self.cur_input = tk.Entry(self, textvariable = self.v2)
        self.cur_input.grid(row = 1, column = 0, columnspan = 8, padx = 3, pady = 5)
        tk.Button(self, text = "del", fg = "OrangeRed", command = self.delete_one).grid(row = 2, column = 0, columnspan = 2, sticky = tk.E + tk.W, padx = 3, pady = 5)
        tk.Button(self, text = "(", command = lambda : self.press("(")).grid(row = 2, column = 2, columnspan = 2, sticky = tk.E + tk.W, padx = 3, pady = 5)
        tk.Button(self, text = ")", command = lambda : self.press(")")).grid(row = 2, column = 4, columnspan = 2, sticky = tk.E + tk.W, padx = 3, pady = 5)
        tk.Button(self, text = "/", command = lambda : self.press("/")).grid(row = 2, column = 6, columnspan = 2, sticky = tk.E + tk.W, padx = 3, pady = 5)
        tk.Button(self, text = "1", command = lambda : self.press("1"), bg = "Black", fg = "white").grid(row = 3, column = 0, columnspan = 2, sticky = tk.E + tk.W, padx = 3, pady = 5)
        tk.Button(self, text = "2", command = lambda : self.press("2"), bg = "Black", fg = "white").grid(row = 3, column = 2, columnspan = 2, sticky = tk.E + tk.W, padx = 3, pady = 5)
        tk.Button(self, text = "3", command = lambda : self.press("3"), bg = "Black", fg = "white").grid(row = 3, column = 4, columnspan = 2, sticky = tk.E + tk.W, padx = 3, pady = 5)
        tk.Button(self, text = "*", command = lambda : self.press("*")).grid(row = 3, column = 6, columnspan = 2, sticky = tk.E + tk.W, padx = 3, pady = 5)
        tk.Button(self, text = "4", command = lambda : self.press("4"), bg = "Black", fg = "white").grid(row = 4, column = 0, columnspan = 2, sticky = tk.E + tk.W, padx = 3, pady = 5)
        tk.Button(self, text = "5", command = lambda : self.press("5"), bg = "Black", fg = "white").grid(row = 4, column = 2, columnspan = 2, sticky = tk.E + tk.W, padx = 3, pady = 5)
        tk.Button(self, text = "6", command = lambda : self.press("6"), bg = "Black", fg = "white").grid(row = 4, column = 4, columnspan = 2, sticky = tk.E + tk.W, padx = 3, pady = 5)
        tk.Button(self, text = "-", command = lambda : self.press("-")).grid(row = 4, column = 6, columnspan = 2, sticky = tk.E + tk.W, padx = 3, pady = 5)
        tk.Button(self, text = "7", command = lambda : self.press("7"), bg = "Black", fg = "white").grid(row = 5, column = 0, columnspan = 2, sticky = tk.E + tk.W, padx = 3, pady = 5)
        tk.Button(self, text = "8", command = lambda : self.press("8"), bg = "Black", fg = "white").grid(row = 5, column = 2, columnspan = 2, sticky = tk.E + tk.W, padx = 3, pady = 5)
        tk.Button(self, text = "9", command = lambda : self.press("9"), bg = "Black", fg = "white").grid(row = 5, column = 4, columnspan = 2, sticky = tk.E + tk.W, padx = 3, pady = 5)
        tk.Button(self, text = "+", command = lambda : self.press("+")).grid(row = 5, column = 6, columnspan = 2, sticky = tk.E + tk.W, padx = 3, pady = 5)
        tk.Button(self, text = ".", command = lambda : self.press(".")).grid(row = 6, column = 0, columnspan = 2, sticky = tk.E + tk.W, padx = 3, pady = 5)
        tk.Button(self, text = "0", command = lambda : self.press("0"), bg = "Black", fg = "white").grid(row = 6, column = 2, columnspan = 2, sticky = tk.E + tk.W, padx = 3, pady = 5)
        tk.Button(self, text = "=", command = self.calculate ,bg = "OrangeRed", fg = "white").grid(row = 6, column = 4, columnspan = 4,sticky = tk.E + tk.W, padx = 3, pady = 5)

    def press(self, new):
        if self.status == "output":
            past = self.cur_input.get()
            self.v1.set(past)
            self.v2.set("")
            self.status = "input"
        string = self.cur_input.get()
        string += new
        self.v2.set(string)

    def delete_one(self):
        new = self.cur_input.get()[:-1]
        self.v2.set(new)

    def calculate(self):
        def precede(a, b):
            """Compare the prior of operator a and b"""
            # the prior of operator
            prior = (
                #   '+'  '-'  '*'  '/'  '('  ')'  '^'  '#'
                ('>', '>', '<', '<', '<', '>', '<', '>'), # '+'
                ('>', '>', '<', '<', '<', '>', '<', '>'), # '-'
                ('>', '>', '>', '>', '<', '>', '<', '>'), # '*'
                ('>', '>', '>', '>', '<', '>', '<', '>'), # '/'
                ('<', '<', '<', '<', '<', '=', '<', ' '), # '('
                ('>', '>', '>', '>', ' ', '>', '>', '>'), # ')'
                ('>', '>', '>', '>', '<', '>', '>', '>'), # '^'
                ('<', '<', '<', '<', '<', ' ', '<', '=')  # '#'
                )

            # operator to index of prior[8][8]
            char2num = {
                '+': 0,
                '-': 1,
                '*': 2,
                '/': 3,
                '(': 4,
                ')': 5,
                '^': 6,
                '#': 7
                }

            return prior[char2num[a]][char2num[b]]

        def operate(a, b, operator):
            """Operate [a operator b]"""
            if operator == '+':
                ans = a + b
            elif operator == '-':
                ans = a - b
            elif operator == '*':
                ans = a * b
            elif operator == '/':
                if b == 0:
                    ans = "VALUE ERROR"
                else:
                    ans = a / b
            elif operator == '^':
                if a == 0 and b == 0:
                    ans = "VALUE ERROR"
                else:
                    ans = a ** b
            return ans

        def calc(exp):
            """Calculate the ans of exp"""
            exp += '#'
            operSet = "+-*/^()#"
            stackOfOperator, stackOfNum = ['#'], []
            pos, ans, index, length = 0, 0, 0, len(exp)
            while index < length:
                e = exp[index]
                if e in operSet:
                    # calc according to the prior
                    topOperator = stackOfOperator.pop()
                    compare = precede(topOperator, e)
                    if compare == '>':
                        try:
                            b = stackOfNum.pop()
                            a = stackOfNum.pop()
                        except:
                            tk.messagebox.showinfo("提示", "格式错误")
                        ans = operate(a, b, topOperator)
                        if ans == "VALUE ERROR":
                            tk.messagebox.showinfo("提示", "值错误")
                        else:
                            stackOfNum.append(ans)
                    elif compare == '<':
                        stackOfOperator.append(topOperator)
                        stackOfOperator.append(e)
                        index += 1
                    elif compare == '=':
                        index += 1
                    elif compare == ' ':
                        tk.messagebox.showinfo("提示", "格式错误")
                else:
                    # get the next num
                    pos = index
                    while not exp[index] in operSet:
                        index += 1
                    temp = exp[pos:index]

                    # delete all 0 of float in the end
                    last = index - 1
                    if '.' in temp:
                        while exp[last] == '0':
                            last -= 1
                        temp = exp[pos:last + 1]

                    try:
                        temp = Decimal(temp)
                    except:
                        tk.messagebox.showinfo("提示", "输入错误")
                    stackOfNum.append(temp)

            if len(stackOfNum) == 1 and stackOfOperator == []:
                return stackOfNum.pop()
            else:
                tk.messagebox.showinfo("提示", "输入错误")
        
        if self.status == "input":
            exp = self.cur_input.get()
            getcontext().prec = self.re_dg
            self.v1.set(exp)
            self.v2.set(calc(exp))
            self.status = "output"
        


if __name__ == "__main__":
    root = tk.Tk()
    root.title("计算器")
    screen(root)
    main_menu()
    calculator = Calculator(root)
    calculator.mainloop() 

最后的代码效果是这样的:
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值