Python(10)--利用tkinter模塊實現一個簡單的計算器功能


#引入相關模塊(math模塊和tkinter模塊)
import math
import tkinter


class MyCalculator:
    #初始化對象
    def __init__(self):
        #設置主界面
        self.root = tkinter.Tk()
        self.root.title('於淼的計算器')
        self.root.minsize(400, 550)

        # 為label標簽設置一個變量
        self.var = tkinter.StringVar()
        # 設置初始值為0
        self.var.set('0')

        # 設置用於存儲運算數據的列表
        self.operation_lists = []
        #設置空字符串,用於截取
        self.metastrs =''
        # 設置是否按下運算符的變量
        self.isoperation = False
        # 調用設置界面的方法
        self.set_main_interface()
        self.root.mainloop()

    #主界面布局方法
    def set_main_interface(self):
        # 顯示結果和操作的區域
        #frame = tkinter.Frame(self.root, width=400, height=100, )
        #frame.pack()
        label = tkinter.Label(self.root, bg='white', textvariable=self.var, anchor='se', font=('黑體', 35), bd=10)
        label.place(x=10, y=10, width=380, height=100)

        # 設置數字按鈕
        button11 = tkinter.Button(self.root, text='%', font=('黑體', 20), command=self.percent)
        button11.place( x=10, y=130, width=90, height=60)

        button12 = tkinter.Button(self.root,text='', font=('黑體', 20), command=self.square)
        button12.place(x=105, y=130, width=90, height=60)

        button13 = tkinter.Button(self.root,text='', font=('黑體', 20), command=self.power)
        button13.place( x=200, y=130, width=90, height=60)

        button14 = tkinter.Button(self.root,text='1/x', font=('黑體', 20), command=self.backwords)
        button14.place( x=295, y=130, width=90, height=60)

        button21 = tkinter.Button(self.root,text='CE', font=('黑體', 20), command=self.clear_CE)
        button21.place( x=10, y=195, width=90, height=60)

        button22 = tkinter.Button(self.root,text='C', font=('黑體', 20), command=self.clear_C)
        button22.place(x=105, y=195, width=90, height=60)

        button23 = tkinter.Button(self.root,text='', font=('黑體', 20), command=self.strip)
        button23.place(x=200, y=195, width=90, height=60)

        button24 = tkinter.Button(self.root,text='÷', font=('黑體', 20), command=lambda: self.symbol('/'))
        button24.place(x=295, y=195, width=90, height=60)

        button31 = tkinter.Button(self.root,text='7', font=('黑體', 20), command=lambda: self.change('7'))
        button31.place(x=10, y=260, width=90, height=60)

        button32 = tkinter.Button(self.root,text='8', font=('黑體', 20), command=lambda: self.change('8'))
        button32.place(x=105, y=260, width=90, height=60)

        button33 = tkinter.Button(self.root,text='9', font=('黑體', 20), command=lambda: self.change('9'))
        button33.place(x=200, y=260, width=90, height=60)

        button34 = tkinter.Button(self.root,text='×', font=('黑體', 20), command=lambda: self.symbol('*'))
        button34.place(x=295, y=260, width=90, height=60)

        button41 = tkinter.Button(self.root,text='4', font=('黑體', 20), command=lambda: self.change('4'))
        button41.place(x=10, y=325, width=90, height=60)

        button42 = tkinter.Button(self.root,text='5', font=('黑體', 20), command=lambda: self.change('5'))
        button42.place(x=105, y=325, width=90, height=60)

        button43 = tkinter.Button(self.root,text='6', font=('黑體', 20), command=lambda: self.change('6'))
        button43.place(x=200, y=325, width=90, height=60)

        button44 = tkinter.Button(self.root,text='', font=('黑體', 20), command=lambda: self.symbol('-'))
        button44.place(x=295, y=325, width=90, height=60)

        button51 = tkinter.Button(self.root,text='1', font=('黑體', 20), command=lambda: self.change('1'))
        button51.place(x=10, y=390, width=90, height=60)

        button52 = tkinter.Button(self.root,text='2', font=('黑體', 20), command=lambda: self.change('2'))
        button52.place(x=105, y=390, width=90, height=60)

        button53 = tkinter.Button(self.root,text='3', font=('黑體', 20), command=lambda: self.change('3'))
        button53.place(x=200, y=390, width=90, height=60)

        button54 = tkinter.Button(self.root,text='', font=('黑體', 20), command=lambda: self.symbol('+'))
        button54.place(x=295, y=390, width=90, height=60)

        button61 = tkinter.Button(self.root,text='±', font=('黑體', 20), command=self.opposite_num)
        button61.place(x=10, y=455, width=90, height=60)

        button62 = tkinter.Button(self.root,text='0', font=('黑體', 20), command=lambda: self.change('0'))
        button62.place(x=105, y=455, width=90, height=60)

        button63 = tkinter.Button(self.root,text='.', font=('黑體', 20), command=lambda: self.change('.'))
        button63.place( x=200, y=455, width=90, height=60)

        button64 = tkinter.Button(self.root,text='=', font=('黑體', 20), command=self.equal)
        button64.place(x=295, y=455, width=90, height=60)
    #計算器各種操作的函數
    #按下數字的函數
    def change(self,num):
        #全局化
        global isoperation
        #判斷是否按下了運算符號
        #如果按下運算符號
        if self.isoperation:
            #將面板中的數據歸0
            self.var.set('0')
            #設置運算符狀態
            self.isoperation = False
        # 獲取原來的數據
        metadata = self.var.get()
        # 判斷原數字是否為0
        if metadata == '0' and num == '.': # 如果為0,判斷輸入的數據是否為符號’.'
            self.var.set('0'+num)
        elif metadata =='0' and num != '.' :# 將按下的數字顯示到標簽中
            self.var.set(num)
        elif metadata in ['除數不能為0','無效輸入','結果未定義']:
            self.var.set(num)
        # 如果不是0,判斷原數字中是否存在符號’.'
        elif '.' in metadata and num == '.':
            return
        #原數字不是0, 且符號'.' 不在原數字中
        else:
            # 將原有數字和當前按下的數字拼合到一起,顯示到標簽中
            self.var.set(metadata + num)
        #獲取面板中的數值,截取最后一個字符
        foredata = self.var.get()[-1]
        #判斷操作列表中的元素
        #如果操作列表不為空,且操作列表最后一元素為運算符號
        if self.operation_lists != [] and self.operation_lists[-1] in ['+','-','*','/']:
            #將面板中的字符加入列表
            self.operation_lists.append(foredata)
            #print(self.operation_lists)
        else:
            #如果操作列表為空
            if self.operation_lists == [] :
                #將截取的字符串加入列表
                self.operation_lists.append(foredata)
                #print(self.operation_lists)
            else:
                #如果操作列表不為空,更新列表最后一個元素
                self.operation_lists[-1] += foredata
                #print(self.operation_lists)


    #按下運算符號的函數
    def symbol(self,sign):
        # 全局化
        global isoperation

        #判斷列表是否為空,不為空時,最后輸入的是否為運算符
        if self.operation_lists != [] and self.operation_lists[-1] in ['+','-','*','/']:
            self.operation_lists[-1] = sign
            return
        #如果列表為空,將當前面板中的數據加入到列表中

        elif self.operation_lists == []:
            #獲取面板中的數據
            foredata = self.var.get()
            #將當前面板中的數據添加到列表中
            self.operation_lists.append(foredata)

        # 將列表中的數據連接成字符串,使用eval函數進行運算
        result = eval(''.join(self.operation_lists))
        # 將運算結果顯示到面板中
        self.var.set(result)
        # 清空列表,將運算結果添加到列表中
        self.operation_lists.clear()
        self.operation_lists.append(str(result))
        # 將按下的運算符也存入列表中
        self.operation_lists.append(sign)
        # 設置運算符的狀態
        self.isoperation = True

    #按下等號的函數
    def equal(self):
        #全局化
        global isoperation
        #判斷除數是否為0
        if '/' in self.operation_lists and self.operation_lists[-1] == '0':
            self.var.set('除數不能為0')
            self.operation_lists.clear()
            return
        elif self.operation_lists!= [] and self.operation_lists[-1] in ['+','-','*','/']:
            self.var.set('結果未定義')


        #如果為空列表
        elif self.operation_lists == []:
            #獲取當前面板中的值
            value = self.var.get()
            #將面板中的值加入列表
            self.operation_lists.append(value)
            self.operation_lists += self.metastrs
            #將列表中的數據組合成字符串,通過eval函數進行運算操作
            strs_num = ''.join(self.operation_lists)
            result = eval(strs_num)
            # 判斷整數位為長度是否大於13
            if len(str(round((result)))) > 13:
                self.var.set('溢出')
            else:
                result = str(result)[0:13]
                # 將運算結果顯示到面板中
                self.var.set(result)

        else:
            #將列表中的數據組合成字符串,通過eval函數進行運算操作
            strs_num = ''.join(self.operation_lists)
            result = eval(strs_num)
            #判斷整數位為長度是否大於13
            if len(str(round((result)))) > 13:
                self.var.set('溢出')
            else:
                result = str(result)[0:13]
                # 將運算結果顯示到面板中
                self.var.set(result)
        self.metastrs = self.operation_lists[-2:]
        #print(self.metastrs)
        # 清空操作列表,便於下次運算使用
        self.operation_lists.clear()

        # 設置運算符狀態
        self.isoperation = True

    #設置清空操作:計算器中的C
    def clear_C(self):
        #將面板中的數據添加到列表里
        self.operation_lists.append(self.var.get())
        #清空用於存儲運算數據的列表
        self.operation_lists.clear()
        #print(self.operation_lists)
        #將面板中的數據歸零
        self.var.set('0')

    # 設置刪除當前數據的操作:計算器中的CE
    def clear_CE(self):
       
        # 清空用於存儲運算數據的列表
        self.operation_lists.pop()
        #print(self.operation_lists)
        # 將面板中的數據歸零
        self.var.set('0')

    #設置刪除鍵
    def strip(self):
        # 獲取當前面板中的數據
        present_data = self.var.get()
        print(present_data)
        #判斷面板中的數據是否為0
        if present_data == '0':
            return
        # 設置刪除數據的操作
        present_data = present_data[:len(present_data)-1]
        print(present_data)
        #判斷刪除后的字符串是否為空
        if present_data =='':#如果為空,設置為0
            self.var.set('0')
            self.operation_lists[-1] = ''
        else:#如果不為空,將刪除后的數據顯示到面板中
            self.var.set(present_data)
            self.operation_lists[-1] = present_data

    #設置1/x鍵
    def backwords(self):
        # 全局化
        global isoperation
        # 獲取當前面板中的數據
        global present_data
        present_data = self.var.get()
        # 判斷列表中數據運算結果是否為0
        if present_data == '0':
            self.var.set('除數不能為0')
        else:
            # 將當前數據取倒數,設置到面板中
            data = '(1' + '/' + present_data+')'
            ##判斷整數位為長度是否大於13
            if len(str(round((eval(data))))) > 13:
                self.var.set('溢出')
            else:
                result = str(eval(data))[0:12]
                self.var.set(result)
            #print(self.operation_lists)
            #將操作列表中的最后一個元素更新為倒數的結果
            self.operation_lists[-1] = str(eval(data))
            print(self.operation_lists)
        # 設置運算符狀態
        self.isoperation = True

    #設置一個數的平方的函數
    def power(self):
        # 全局化
        global isoperation
        # 獲取當前面板中的數據
        present_data = self.var.get()
        # print(present_data)
        # 將當前數據進行平方運算后,設置到面板中
        data = 'math.pow' + '(' + present_data +','+ '2' +')'
        # 判斷整數位為長度是否大於13
        if len(str(round(eval(data)))) > 13:
            self.var.set('溢出')
        else:
            result = str(eval(data))[0:12]
            self.var.set(result)
        self.operation_lists[-1] = str(eval(data))
        # 設置運算符狀態
        self.isoperation = True

    #設置一個數據的開平方運算
    def square(self):
        # 全局化
        global isoperation
        # 獲取當前面板中的數據
        present_data = self.var.get()
        #判斷數值的正負
        if present_data[0] == '-':
            self.var.set('無效輸入')
        else:
            # 將當前數據進行平方運算后,設置到面板中
            data = 'math.sqrt' + '(' + present_data +')'
            result = str(eval(data))[0:12]
            self.var.set(result)
            self.operation_lists[-1] = str(eval(data))
        # 設置運算符狀態
        self.isoperation = True

    #設置’%‘的運算
    def percent(self):
        # 全局化
        global isoperation
        # 獲取當前面板中的數據
        present_data = self.var.get()
        # 將當前數據進行%運算后,設置到面板中
        data = present_data + '*' +'0.01'
        result = str(eval(data))[0:12]
        self.var.set(result)
        self.operation_lists[-1] = str(eval(data))
        # 設置運算符狀態
        self.isoperation = True

    #求反的運算
    def opposite_num(self):
        # 全局化
        global isoperation
        # 獲取當前面板中的數據
        present_data = self.var.get()

        if present_data[0] == '-':
            self.var.set(present_data[1:])
        elif present_data[-1] == '0':
            self.var.set('0')
        else:
            self.var.set('-' + present_data)
        self.operation_lists[-1] = self.var.get()
        print(self.operation_lists)
        # 設置運算符狀態
        self.isoperation = True



#實例化對象
my= MyCalculator()

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM