Python實現簡易圖形用戶界面計算器


一:計算器界面

使用tkinter實現一個支持四則運算的簡易圖形用戶界面計算器

界面和功能

筒易圖形用戶界面計算器的界面設計如圖所示

  • 第一行顯示輸入的運算表達式;
  • 第二行顯示當前輸入的操作數或運算結果;
  • 第三行到第七行爲計算器按鈕。

二:計算器設計思路

思維和設計方法

  • 創建一個繼承於Frame的類Calc來實現計算器。

  • 實現界面。在Calc構造函數,創建簡易圖形用戶界面計算器的各個組件對象。

  1. 構造函數中,
    創建兩個Label對象:exprLabel (用於顯示運算表達式)、resultLabel (用於顯示當前輸入操作數或者運算結果)。
    創建兩個StringVar實例對象expr和result,並分別綁定到對應得Label對象。使用grid佈局,在第一行和第二行顯示兩個Label對象。
# 顯示運算表達式
self.expr = tk.StringVar()  
self.expr.set('')
self.exprLabel = tk.Label(self, font = ('Helvetica', 20),
                          fg = '#f40', width = 42, anchor='w', textvariable = self.expr)
self.exprLabel.grid(row = 0, column = 0, columnspan = 4)

# 顯示結果
self.result = tk.StringVar()  
self.result.set(0)
self.resultLabel = tk.Label(self, font = ('Helvetica', 20),
                            width = 42, anchor='e', textvariable=self.result)
self.resultLabel.grid(row = 1, column = 0, columnspan = 4)
  1. 使用一個二維列表存儲按鈕標籤
    然後使用嵌套循環的方法創建和佈局各個按鈕。在循環中定義事件處理函數cmd().默認參數爲按鈕標籤buttons[r][c]),調用實例方法click(key),從而實現使用一一個函數(使用默認參數)處理所有的按鈕事件。
buttons = [[ 'CE', 'C', '←', '/'],
		   ['7', '8', '9', '×'],
		   ['4', '5', '6', '-'],
		   ['1', '2', '3', '+'],
		   ['±', '0', '.', '=']]
  • 事件處理。在事件處理函數click(self, key)中,按key的值,執行不同的處理邏輯。在構造函數中,創建一個變量startOfNextOperand (默認爲True),用於表示是否開始輸入下一個操作數。如果變量startOfNextOperand爲True時,按數字鍵會設置當前輸入爲0,重新輸入新的操作數;如果變量startOfNextOperand爲False時,繼續輸入當前操作數的下一個數字字符。
  1. 按數字或者小數點按鈕鍵。把輸入的字符鏈接到當前輸入操作數之後。
  2. 按 ← 按鈕鍵,可以清除當前輸入操作數的最後一個字符。
  3. 按 ± 按鈕鍵,切換當前輸入數的正負號。
  4. 按 C 按鈕鍵,清除當前輸入的操作數。
  5. 按返算符 /、×、-、+ 按鈕鍵時,顯示到目前爲止的輸入的運算表達式。
  6. 按 = 按鈕鍵,執行運算,顯示運算結果。
  • if__name__ == __main__:語句中編寫測試代碼,創建Calculate對象,並顯示運行結果。

calculator.py

import tkinter as tk

class Calculate(tk.Frame):
    def __init__(self, parent = None):
        """構造函數"""
        tk.Frame.__init__(self, parent)
        self.pack()
        self.startOfNextOperand = True  # 開始輸入下一個操作數

        # 顯示運算表達式
        self.expr = tk.StringVar()  
        self.expr.set('')
        self.exprLabel = tk.Label(self, font = ('Helvetica', 20),
                                  fg = '#f40', width = 42, anchor='w', textvariable = self.expr)
        self.exprLabel.grid(row = 0, column = 0, columnspan = 4)

        # 顯示結果
        self.result = tk.StringVar()  
        self.result.set(0)
        self.resultLabel = tk.Label(self, font = ('Helvetica', 20),
                                    width = 42, anchor='e', textvariable=self.result)
        self.resultLabel.grid(row = 1, column = 0, columnspan = 4)

        # 計算器按鈕的按鈕,使用二維列表表示
        buttons = [[ 'CE', 'C', '←', '/'],
                   ['7', '8', '9', '×'],
                   ['4', '5', '6', '-'],
                   ['1', '2', '3', '+'],
                   ['±', '0', '.', '=']]

        # 創建和佈局3到7行各個按鈕
        for r in range(5):
            for c in range(4):
                # 定義事件處理函數cmd(),默認參數爲按鈕標籤buttons[r][c]
                def cmd(key = buttons[r][c]):
                    self.click(key)
                if(r == 0 or c == 3):
                    button = tk.Button(self, text = buttons[r][c], bg = '#008c8c', fg = '#fff', 
                              width=15, font = ('Helvetica', 15), command = cmd)
                else:
                    button = tk.Button(self, text = buttons[r][c], bg = '#fff', fg = '#666', 
                              width=15, font = ('Helvetica', 15), command = cmd)
                button.grid(row = r+2, column = c)

    def click(self, key):
        """事件處理"""
        if key == '=':   #按等號鍵時, 求值, 並顯示結果
            result = eval(self.expr.get() + self.result.get())
            self.result.set(result)
            self.expr.set('')
            self.startOfNextOperand = True
        elif key in '+-/×':
            if key == '×': key = '*'
            resultExpr = self.expr.get() + self.result.get() + key
            self.expr.set(resultExpr)
            self.result.set(0)
            self.startOfNextOperand = True
        elif key == 'C':  # 全部清空, 回到初始狀態
            self.expr.set('')
            self.result.set(0)
        elif key == 'CE':  # 清空當前輸入
            self.result.set(0)
        elif key == '←':
            oldnum = self.result.get()
            if len(oldnum) == 1: # 只有一個字符
                newnum = 0
            else:
                newnum = oldnum[:-1]
            self.result.set(newnum)
        elif key == '±':  # 正負號,切換正負號
            oldnum = self.result.get()  # 獲取原來的值
            if oldnum[0] == '-':
                newnum = oldnum[1:]
            else:
                newnum = '-' + oldnum
            self.result.set(newnum)
        else: # 按數字或者小數點鍵
            if self.startOfNextOperand:
                self.result.set(0)
                self.startOfNextOperand = False
            oldnum = self.result.get()  # 獲取原來的值
            if oldnum == '0':
                self.result.set(key)
            else:
                newnum = oldnum + key
                self.result.set(newnum)

if __name__ == '__main__':
    root = tk.Tk()
    root.title('簡易計算器')
    calculate = Calculate(root)
    root.mainloop()

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章