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

news2024/9/21 21:43:56

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自己也可以设置的。
正常工作!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1953071.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python在类中手动定义标准化输出函数

在深度学习等训练框架中&#xff0c;有时候需要对模型的名称、参数量、训练进度、中间结果等进行标准化输出&#xff0c;从而方便实时查看代码运行情况&#xff0c;这时&#xff0c;可以在类中手动定义如下标准化的输出函数&#xff0c;然后在需要输出的地方进行调用即可。 首…

免费【2024】springboot 超市货品信息管理系统

博主介绍&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化…

修复SteamUI.dll加载失败的指南,快速修复failed to load steamui.dll

在使用Steam平台进行游戏下载、安装和运行时&#xff0c;可能会遇到一些系统错误&#xff0c;比如“failed to load steamui.dll”。这个错误通常意味着Steam的用户界面库文件steamui.dll出现了问题。本文将详细介绍steamui.dll文件的相关信息以及如何修复这一问题。 一.什么是…

vue 开发环境配置

1. nvm 安装 在 github上下载 最新的 nvm 包 https://github.com/coreybutler/nvm-windows/releases或者在 csdn 上下载&#xff08;从github上迁移&#xff0c;方便下载&#xff09;https://download.csdn.net/download/u011171506/89585197 下载后不用修改任何配置&#x…

Opencv学习项目4——手部跟踪

上一篇博客我们介绍了mediapipe库和对手部进行了检测&#xff0c;这次我们进行手部关键点的连线 代码实现 import cv2 import mediapipe as mpcap cv2.VideoCapture(1) mpHands mp.solutions.hands hands mpHands.Hands() mpDraw mp.solutions.drawing_utilswhile True:…

树莓派智能家居中枢

一个先进的枢纽&#xff0c;使智能家居系统更智能、更可定制、更易于控制 Homey Pro由树莓派 Compute Module 4 供电,Homey Pro 为用户提供了一个单一界面,用于控制和监控来自不同品牌的所有智能家居设备。它完全在本地网络上运行,而不是依赖云端,从而实现了最低的延迟、最高的…

对Linux目录结构的补充

&#x1f4d1;打牌 &#xff1a; da pai ge的个人主页 &#x1f324;️个人专栏 &#xff1a; da pai ge的博客专栏 ☁️宝剑锋从磨砺出&#xff0c;梅花香自苦寒来 ☁️运维工程师的职责&#xff1a;监…

【数据结构】哈希表的模拟实现

文章目录 1. 哈希的概念2. 哈希表与哈希函数2.1 哈希冲突2.2 哈希函数2.3 哈希冲突的解决2.3.1 闭散列&#xff08;线性探测&#xff09;2.3.2 闭散列的实现2.3.3 开散列(哈希桶)2.3.4 开散列的实现 2.4 开散列与闭散列比较 1. 哈希的概念 在我们之前所接触到的所有的数据结构…

【C语言项目】 以链表实现的管理系统(注册、登录、对表进行数据操作)

第一次编辑这么长的文章&#xff0c;如果对你有帮助&#xff0c;可以点赞收藏一下一起学习&#xff01;一起进步&#xff01; 目录 一、项目介绍 二、代码介绍 三、小记 四、完整代码 五、输出结果展示 1、成功将终端输入的用户姓名和密码分别存入到.txt文件中 2、登陆成…

cpp学习记录03

结构体 定义&#xff1a;用户自定义符合数据类型&#xff0c;可以包含不同类型的不同成员。 //声明结构体 struct 结构体类型&#xff08;自己起名&#xff09; {成员1类型 成员1名称&#xff1b;。。。成员N类型 成员N名称&#xff1b;} 基本用法&#xff08;类似class&…

探索 Electron:构建用户友好的登录页面流程

Electron是一个开源的桌面应用程序开发框架&#xff0c;它允许开发者使用Web技术&#xff08;如 HTML、CSS 和 JavaScript&#xff09;构建跨平台的桌面应用程序&#xff0c;它的出现极大地简化了桌面应用程序的开发流程&#xff0c;让更多的开发者能够利用已有的 Web 开发技能…

88年汉城奥运追忆:差距尤存,出路何在

&#xff08;35年前的文章&#xff0c;摘自1989年2月1日《大众日报》&#xff09; 差距尤存 出路何在 ——汉城奥运会后的思索 刘伟 一项调查表明&#xff1a;在当今中国中学生最喜爱的十本杂志中&#xff0c;竟没有一本是体育类杂志&#xff1b;在城市工人、干部、科技人员家…

搜索引擎项目(四)

SearchEngine 王宇璇/submit - 码云 - 开源中国 (gitee.com) 基于Servlet完成前后端交互 WebServlet("/searcher") public class DocSearcherServlet extends HttpServlet {private static DocSearcher docSearcher new DocSearcher();private ObjectMapper obje…

【前端/js】使用js读取本地文件(xml、二进制)内容

目录 说在前面FileReaderDOMParser文本文件二进制文件 说在前面 浏览器版本&#xff1a;Microsoft Edge 126.0.2 (正式版本) (64 位) FileReader MDNFileReader 接口允许 Web 应用程序异步读取存储在用户计算机上的文件&#xff08;或原始数据缓冲区&#xff09;的内容&#x…

Golang 高性能 Websocket 库 gws 使用与设计(一)

前言 大家好这里是&#xff0c;白泽&#xff0c;这期分析一下 golang 开源高性能 websocket 库 gws。 视频讲解请关注&#x1f4fa;B站&#xff1a;白泽talk 介绍 gws&#xff1a;https://github.com/lxzan/gws &#xff5c;GitHub &#x1f31f; 1.2k&#xff0c;高性能的 …

STM32(七):STM32指南者-通信实验

目录 一、基本概念通讯基本概念1、串行和并行2、同步通讯与异步通讯3、全双工、半双工、单工4、通讯速率 USART基本概念1、串口通讯基本概念2、物理层3、协议层4、指南者的串口USART I2C基本概念SPI基本概念 二、USART串口实验前期准备1、安装安装 USB 转串口驱动_CH3402、野火…

【中项】系统集成项目管理工程师-第5章 软件工程-5.1软件工程定义与5.2软件需求

前言&#xff1a;系统集成项目管理工程师专业&#xff0c;现分享一些教材知识点。觉得文章还不错的喜欢点赞收藏的同时帮忙点点关注。 软考同样是国家人社部和工信部组织的国家级考试&#xff0c;全称为“全国计算机与软件专业技术资格&#xff08;水平&#xff09;考试”&…

代码随想录算法训练营day22 | 77. 组合、216.组合总和III 、17.电话号码的字母组合

碎碎念&#xff1a;加油 参考&#xff1a;代码随想录 回溯算法理论基础 回溯和递归是相辅相成的&#xff0c;只要有递归&#xff0c;就会有回溯。回溯通常在递归函数的下面。 回溯搜索到法的效率&#xff1a; 它其实是纯暴力的做法&#xff0c;不是一个高效的算法。 回溯法能…

将控制台内容输出到文本文件

示例代码&#xff1a; Imports System.IO Module Module1Sub Main()Dim fs As New FileStream("D:\Desktop\test\输出结果.txt", FileMode.Create, FileAccess.Write, FileShare.None)Dim sw As New StreamWriter(fs)Console.SetOut(sw)Console.SetError(sw)For i …

Spring 自定义集合实现策略

Spring 自定义集合实现策略 日常开发中&#xff0c;如果遇到复杂业务通常会用一个接口实现多个实现类。需要根据对应参数判断获取不同实现类。例如支付场景&#xff0c;根据选择支付方式&#xff0c;选择相应路由。如果实现类不多&#xff0c;通常会这样。如果实现类多了&…