简易图形用户界面计算器(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()

三:完整代码获取


参考资料:

发布了146 篇原创文章 · 获赞 287 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/Zhangguohao666/article/details/103948608