python语言利用Tkinter实现GUI计算器|(二)优化计算器:过滤用户不合理的输入

python语言利用Tkinter实现GUI计算器

python语言利用Tkinter实现GUI计算器|(一)计算器基本功能设计
python语言利用Tkinter实现GUI计算器|(二)优化计算器
python语言利用Tkinter实现GUI计算器|(三)pyinstaller打包:带图标计算器


Calculator计算器的优化问题

在上一篇博客:Python语言利用tkinter库实现用户界面计算器的过程中,有如下几个方面待优化,可使Calculator更健壮。

1.关于用户乱输入,使软件奔溃的问题。

本计算器计算功能是通过获取将输入表达式,利用eval()函数来执行python代码字符串的。那么就要杜绝不合理的输入表达式,如何过滤掉用户不合理的输入,需要在程序执行前设置try...except...else...finally语句,来捕捉用户的异常输入,设置异常输入响应为Error。Calculator类中,执行run函数修改如下:

在这里插入图片描述
在这里插入图片描述

2.优化冗于代码

优化方向

  • 初始化布局页面代码冗余;
  • lambda匿名函数包裹回调函数时传参的问题

代码实现:这里主要优化初始化函数,其他函数采用继承。
优化计算器类Calc继承Calculator的back,clear,run,getNum。增加initPage来定义页面控件布局。

# 计算器,优化程序
class Calc(Calculator):
    def __init__(self, master):
        self.master = master
        self.master.title("Calculator")
        self.master.resizable(0, 0)  # 设置窗口不可拉伸
        self.master.geometry('320x420')  # 设置主窗口的初始尺寸

        self.result = StringVar()  # 用于显示结果的可变文本
        self.equation = StringVar()  # 显示计算方程
        self.result.set(' ')
        self.equation.set('0')

        self.labels = ['<-', '(', ')', '÷',
                       '7', '8', '9', '*',
                       '4', '5', '6', '-',
                       '1', '2', '3', '+',
                       'MC', '0', '.', '=',
                       ]
        # 显示框
        self.show_result_eq = Label(self.master, bg='white', fg='black',
                                    font=('Arail', '16'), bd='0',
                                    textvariable=self.equation, anchor='se')
        self.show_result = Label(self.master, bg='white', fg='black',
                                 font=('Arail', '20'), bd='0',
                                 textvariable=self.result, anchor='se')
        # 按钮
        # self.button_dict = {}
        # Layout布局
        self.show_result_eq.place(x='10', y='10', width='300', height='50')
        self.show_result.place(x='10', y='60', width='300', height='50')

        self.initPage()

    def initPage(self):
        X = ['10', '90', '170', '250']
        Y = ['150', '205', '260', '315', '370']
        lengths = len(self.labels)  # 20
        y_ = -1
        # 设置按钮并布局
        for label in self.labels:
            print(label)
            index = self.labels.index(label)
            x_ = index % 4
            if x_ == 0:
                y_ += 1

            if label == '<-':
                button = Button(self.master, text=label, bg='DarkGray', command=self.back)
                button.place(x=X[x_], y=Y[y_], width='60', height='40')
            elif label == '=':
                button = Button(self.master, text=label, bg='DarkGray', command=self.run)
                button.place(x=X[x_], y=Y[y_], width='60', height='40')
            elif label == 'MC':
                button = Button(self.master, text=label, bg='DarkGray', command=self.clear)
                button.place(x=X[x_], y=Y[y_], width='60', height='40')
            else:
                # 因为lambda函数有传参功能,但只有调用的时候才传参,所以数字按钮永远会调用最后一个label值。解决方案是自己洗一个button来保存label值
                button = NumButton(self.master, text=label, bg='DarkGray', fun=self.getNum)
                button.btn.place(x=X[x_], y=Y[y_], width='60', height='40')
            # self.button_dict[label] = button

重点:以上代码,倒数第二行,我采用自定义的NumButton,而不是原有的Butoon。
因为即使匿名函数lambda函数有传参功能,但只有调用的时候才传参,所以for循环到最后,label变量的值永远为列表最后一个=等于符号,一度让人无解,只能自定义一个按钮类型NumButton,来保存中间值。使按钮们都有自己的文本值,并且command回调的时候能够准确传参。

class NumButton():
    def __init__(self, frame, text, fun, **kwargs):
        # side = kwargs.get('side') if 'side' in kwargs else ()  # 此处没用上
        self.btn = Button(
            frame,
            text=text,
            activeforeground="blue",
            activebackground="pink",
            bg='DarkGray',
            command=lambda: fun(text)
        )

注意
形式参数frame, text, fun
frame是根部件。
text按钮的标签文本,
fun函数对象,就是待回调的函数。

3.测试计算器

if __name__ == "__main__":
    root = Tk()
    # my_cal = Calculator(root)
    my_cal = Calc(root)
    root.mainloop()

在这里插入图片描述
自定义的NumButton设置了按钮激活时背景和字体的颜色变化,所以有点颜色。Button自己也可以设置的。
正常工作!!

  • 17
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是一个简单的计算器GUI程序,使用PythonTkinter库。 ```python from tkinter import * # 创建窗口 window = Tk() window.title("Calculator") # 显示结果的文本框 result = Entry(window, width=20, borderwidth=5) result.grid(row=0, column=0, columnspan=4, padx=10, pady=10) # 按钮点击事件 def button_click(number): current = result.get() result.delete(0, END) result.insert(0, str(current) + str(number)) def button_clear(): result.delete(0, END) def button_add(): first_number = result.get() global f_num global math math = "addition" f_num = int(first_number) result.delete(0, END) def button_subtract(): first_number = result.get() global f_num global math math = "subtraction" f_num = int(first_number) result.delete(0, END) def button_multiply(): first_number = result.get() global f_num global math math = "multiplication" f_num = int(first_number) result.delete(0, END) def button_divide(): first_number = result.get() global f_num global math math = "division" f_num = int(first_number) result.delete(0, END) def button_equal(): second_number = result.get() result.delete(0, END) if math == "addition": result.insert(0, f_num + int(second_number)) if math == "subtraction": result.insert(0, f_num - int(second_number)) if math == "multiplication": result.insert(0, f_num * int(second_number)) if math == "division": result.insert(0, f_num / int(second_number)) # 创建按钮 button_1 = Button(window, text="1", padx=40, pady=20, command=lambda: button_click(1)) button_2 = Button(window, text="2", padx=40, pady=20, command=lambda: button_click(2)) button_3 = Button(window, text="3", padx=40, pady=20, command=lambda: button_click(3)) button_4 = Button(window, text="4", padx=40, pady=20, command=lambda: button_click(4)) button_5 = Button(window, text="5", padx=40, pady=20, command=lambda: button_click(5)) button_6 = Button(window, text="6", padx=40, pady=20, command=lambda: button_click(6)) button_7 = Button(window, text="7", padx=40, pady=20, command=lambda: button_click(7)) button_8 = Button(window, text="8", padx=40, pady=20, command=lambda: button_click(8)) button_9 = Button(window, text="9", padx=40, pady=20, command=lambda: button_click(9)) button_0 = Button(window, text="0", padx=40, pady=20, command=lambda: button_click(0)) button_add = Button(window, text="+", padx=39, pady=20, command=button_add) button_subtract = Button(window, text="-", padx=41, pady=20, command=button_subtract) button_multiply = Button(window, text="*", padx=40, pady=20, command=button_multiply) button_divide = Button(window, text="/", padx=41, pady=20, command=button_divide) button_clear = Button(window, text="Clear", padx=79, pady=20, command=button_clear) button_equal = Button(window, text="=", padx=91, pady=20, command=button_equal) # 将按钮放置到窗口中 button_1.grid(row=3, column=0) button_2.grid(row=3, column=1) button_3.grid(row=3, column=2) button_4.grid(row=2, column=0) button_5.grid(row=2, column=1) button_6.grid(row=2, column=2) button_7.grid(row=1, column=0) button_8.grid(row=1, column=1) button_9.grid(row=1, column=2) button_0.grid(row=4, column=0) button_clear.grid(row=4, column=1, columnspan=2) button_add.grid(row=5, column=0) button_subtract.grid(row=6, column=0) button_multiply.grid(row=6, column=1) button_divide.grid(row=6, column=2) button_equal.grid(row=5, column=1, columnspan=2) # 运行窗口 window.mainloop() ``` 运行程序后,将会看到一个简单的计算器GUI。 ![calculator.png](https://i.loli.net/2021/03/12/6mPZ9cU8zET1dLg.png) 这个GUI程序支持基本的加、减、乘、除操作,以及清空、等号操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柏常青

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值