【使用Python和tkinter库创建的复杂计算器示例】

news2024/10/21 5:38:23

为了创建一个更复杂的计算器,我们可以增加一些额外的功能,比如支持括号、更复杂的表达式解析(包括运算符的优先级处理),以及可能的用户交互改进。以下是一个使用Python和tkinter库创建的复杂计算器示例,它支持括号、加减乘除运算以及运算符的优先级处理。

import tkinter as tk
import re

class AdvancedCalculator:
    def __init__(self, root):
        self.root = root
        self.root.title("复杂计算器")

        self.expression_var = tk.StringVar()
        self.expression_var.set("")

        self.result_var = tk.StringVar()
        self.result_var.set("0")

        self.create_widgets()

    def create_widgets(self):
        # 创建显示表达式的Entry
        self.expression_entry = tk.Entry(self.root, textvariable=self.expression_var, font=('Arial', 18), bd=8, insertwidth=4, width=26, borderwidth=4)
        self.expression_entry.grid(row=0, column=0, columnspan=4, padx=10, pady=10)

        # 创建显示结果的Entry
        self.result_entry = tk.Entry(self.root, textvariable=self.result_var, font=('Arial', 24), bd=10, insertwidth=2, width=10, state='readonly', borderwidth=4)
        self.result_entry.grid(row=1, column=0, columnspan=4, pady=10)

        # 创建按钮并放置在网格中
        buttons = [
            '7', '8', '9', '/',
            '4', '5', '6', '*',
            '1', '2', '3', '-',
            'C', '0', '=', '+',
            '(', ')'
        ]

        row_val = 2
        col_val = 0

        for button in buttons:
            command = lambda x=button: self.click_event(x)
            tk.Button(self.root, text=button, padx=20, pady=20, font=('Arial', 18), command=command).grid(row=row_val, column=col_val)

            col_val += 1
            if col_val > 3:
                col_val = 0
                row_val += 1

    def click_event(self, key):
        current_expression = self.expression_var.get()

        if key == "=":
            try:
                result = self.evaluate_expression(current_expression)
                self.result_var.set(str(result))
            except Exception as e:
                self.result_var.set("错误")
        elif key == "C":
            self.expression_var.set("")
            self.result_var.set("0")
        else:
            self.expression_var.set(current_expression + key)

    def evaluate_expression(self, expression):
        # 这是一个简单的表达式求值函数,使用栈来处理运算符的优先级
        def precedence(op):
            if op in ('+', '-'):
                return 1
            if op in ('*', '/'):
                return 2
            return 0

        def apply_op(a, b, op):
            if op == '+': return a + b
            if op == '-': return a - b
            if op == '*': return a * b
            if op == '/':
                if b == 0:
                    raise ZeroDivisionError("除数不能为零")
                return a / b

        numbers = []
        operators = []
        i = 0
        while i < len(expression):
            if expression[i] == ' ':
                i += 1
                continue

            if expression[i] == '(':
                operators.append(expression[i])

            elif expression[i].isdigit() or expression[i] == '.':
                val = 0
                decimal_place = -1
                while (i < len(expression) and
                       (expression[i].isdigit() or expression[i] == '.')):
                    if expression[i] == '.':
                        decimal_place = len(val.split('.'))
                    elif decimal_place == -1:
                        val = (val * 10) + int(expression[i])
                    else:
                        decimal_val = int(expression[i]) / (10 ** (len(str(val).split('.'))[1] if '.' in str(val) else 0 + 1))
                        val += decimal_val
                    i += 1
                i -= 1  # Correct the index for the next iteration
                numbers.append(float(str(val)))

            elif expression[i] in '+-*/':
                while (len(operators) != 0 and
                       precedence(operators[-1]) >= precedence(expression[i])):
                    operators.pop()
                    if len(numbers) >= 2:
                        b = numbers.pop()
                        a = numbers.pop()
                        result = apply_op(a, b, operators.pop())
                        numbers.append(result)
                operators.append(expression[i])

            elif expression[i] == ')':
                while (len(operators) != 0 and operators[-1] != '('):
                    if len(numbers) >= 2:
                        b = numbers.pop()
                        a = numbers.pop()
                        result = apply_op(a, b, operators.pop())
                        numbers.append(result)
                operators.pop()  # Remove '(' from the stack

            i += 1

        while len(operators) != 0:
            if len(numbers) >= 2:
                b = numbers.pop()
                a = numbers.pop()
                result = apply_op(a, b, operators.pop())
                numbers.append(result)

        return numbers[0]

if __name__ == "__main__":
    root = tk.Tk()
    app = AdvancedCalculator(root)
    root.mainloop()

代码说明

  1. AdvancedCalculator类

    • 初始化方法__init__:设置窗口标题,创建并初始化用于显示表达式和结果的StringVar变量,然后调用create_widgets方法创建按钮和文本框。
    • create_widgets方法:创建用于显示表达式和结果的Entry以及用于输入操作的按钮,并将它们放置在网格布局中。
    • click_event方法:处理按钮点击事件。根据点击的按钮更新显示表达式或计算结果。
    • evaluate_expression方法:这是一个简单的表达式求值函数,它使用栈来处理运算符的优先级。该函数支持加减乘除运算以及括号。
  2. 主程序

    • 创建Tk根窗口实例。
    • 创建AdvancedCalculator应用实例,传入根窗口。
    • 进入mainloop循环,等待用户交互。

这个计算器支持复杂的数学表达式输入,并能够根据运算符的优先级以及括号进行正确的计算。注意,虽然这个示例已经相对复杂,但在实际应用中,可能需要更多的错误处理和边界情况检查,以确保计算器的健壮性和准确性。

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

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

相关文章

线程池:高效管理并发任务的利器

线程池&#xff1a;高效管理并发任务的利器 什么是线程池&#xff1f; 线程池&#xff08;Thread Pool&#xff09;是Java并发编程中的一种设计模式&#xff0c;旨在通过重复利用线程资源&#xff0c;来提高程序执行效率。线程池的主要思想是提前创建一组可供使用的线程&#…

归一化输入

当输入的不同的特征取值范围差异过大&#xff0c;取得对应参数差别也会很大&#xff0c;在对参数进行优化的过程中&#xff0c;参数小的维度步长较小&#xff0c;参数大的维度步长较大&#xff0c;优化过程中路径曲折&#xff0c;将输入归一化&#xff0c;使特征取值范围差别小…

相控阵雷达电特性matlab模拟与仿真,带GUI界面,对比有限扫描阵,稀疏阵,多波束阵,共形阵等

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 相控阵雷达作为一种先进的雷达技术&#xff0c;具有高分辨率、多功能、快速扫描等优点&#xff0c;在军事和民用领域都有着广泛的应用。相控阵雷达的天线系统是其核心组成部分…

C#线性变换——缩放

前言&#xff1a; 大家好&#xff0c;我是上位机马工&#xff0c;硕士毕业4年年入40万&#xff0c;目前在一家自动化公司担任软件经理&#xff0c;从事C#上位机软件开发8年以上&#xff01;我们在C#开发中经常需要对平面中的坐标进行一些变换&#xff0c;比如缩放、旋转等&…

数据结构:二叉树、堆

目录 一.树的概念 二、二叉树 1.二叉树的概念 2.特殊类型的二叉树 3.二叉树的性质 4.二叉树存储的结构 三、堆 1.堆的概念 2.堆的实现 Heap.h Heap.c 一.树的概念 注意&#xff0c;树的同一层中不能有关联&#xff0c;否侧就不是树了&#xff0c;就变成图了&#xff…

PCL 点云配准 Trimed-ICP算法(精配准

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.1.1 perform_standard_icp 函数 2.1.2 perform_trimmed_icp 函数 2.1.3 visualize_registration 函数 2.2完整代码 PCL点云算法汇总及实战案例汇总的目录地址链接&#xff1a; PCL点云算…

国庆旅游高峰期,如何利用可视化报表来展现景区、游客及消费数据

国庆黄金周&#xff0c;作为国内旅游市场的年度盛宴&#xff0c;总是吸引着无数游客的目光。今年&#xff0c;随着旅游市场的强劲复苏&#xff0c;各大景区又再次迎来游客流量的高峰。全国国内出游7.65亿人次&#xff0c;同比增长5.9%&#xff0c;国内游客出游总花费7008.17亿元…

大型企业软件开发是什么样子的? - Web Dev Cody

引用自大型企业软件开发是什么样子的&#xff1f; - Web Dev Cody_哔哩哔哩_bilibili 一般来说 学技术的时候 我们会关注 开发语言特性 &#xff0c;各种高级语法糖&#xff0c;底层技术 但是很少有关注到企业里面的开发流程&#xff0c;本着以终为始&#xff08;以就业为导向…

界面控件Telerik UI for WPF 2024 Q3亮点 - 支持禁用数据过滤等

Telerik UI for WPF拥有超过100个控件来创建美观、高性能的桌面应用程序&#xff0c;同时还能快速构建企业级办公WPF应用程序。UI for WPF支持MVVM、触摸等&#xff0c;创建的应用程序可靠且结构良好&#xff0c;非常容易维护&#xff0c;其直观的API将无缝地集成Visual Studio…

[Linux网络编程]03-TCP协议

一.TCP协议数据通信的过程 TCP数据报如下&#xff0c;数据报中的标志位双端通信的关键。 三次握手: 1.客户端向服务端发送SYN标志位&#xff0c;请求建立连接&#xff0c;同时发送空包 2.服务端向客户端回发ACK标志位(即确认标志位&#xff0c;任何一端发送数据后都需要另一端…

asyn驱动示例-int32driver

驱动程序源代码int32Driver.c&#xff1a; #include <stddef.h> #include <string.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <ctype.h>#include <cantProceed.h> #include <epicsStdio.h> #i…

官龙村捐赠图书整理有感

今天&#xff08;2024年10月20日&#xff09;&#xff0c;我有幸参加了在深圳南山区西丽官龙村举行的义工活动&#xff0c;主要任务是整理捐赠的图书&#xff0c;并根据小学和中学的需求进行分类打包。这次活动不仅让我体会到了劳动的辛苦&#xff0c;更让我感受到了助人为乐的…

【AIGC】第一性原理下的ChatGPT提示词Prompt设计:系统信息与用户信息的深度融合

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | ChatGPT 文章目录 &#x1f4af;前言&#x1f4af;第一性原理与ChatGPT提示词Prompt设计应用第一性原理于ChatGPT提示词Prompt设计系统信息和用户信息的融合实际应用结论 &#x1f4af;系统信息与用户信息的定义和重要性系…

鸿蒙中富文本编辑与展示

富文本在鸿蒙系统如何展示和编辑的&#xff1f;在文章开头我们提出这个疑问&#xff0c;带着疑问来阅读这篇文章。 富文本用途可以展示图文混排的内容&#xff0c;在日常App 中非常常见&#xff0c;比如微博的发布与展示&#xff0c;朋友圈的发布与展示&#xff0c;都在使用富文…

C++高阶:红黑树实现

目录 一.红黑树的概念 1.1红黑树的规则 1.2红黑树的效率 二.红黑树的实现 2.1红黑树的结构 2.2红黑树的插入 2.2.1插入的大致过程 2.2.2情况一&#xff1a;变色 ​编辑 2.2.3情况二&#xff1a;单旋变色 2.2.4情况三&#xff1a;双旋变色 2.3插入代码实现 2.4红黑树的…

【网络安全】简单P1:通过开发者工具解锁专业版和企业版功能

未经许可,不得转载。 文章目录 前言发现过程前言 在探索一个SaaS平台的过程中,我发现了一个漏洞,使得我能够在无需订阅的情况下解锁高级(专业/企业)功能。 发现过程 我使用一个没有任何高级功能的基本用户账户进行常规登录。在浏览平台时,我注意到某些按钮和功能上带有…

【C++STL】list的基本介绍与使用方式

✨ Blog’s 主页: 白乐天_ξ( ✿&#xff1e;◡❛) &#x1f308; 个人Motto&#xff1a;他强任他强&#xff0c;清风拂山冈&#xff01; &#x1f525; 所属专栏&#xff1a;C深入学习笔记 &#x1f4ab; 欢迎来到我的学习笔记&#xff01; 一、list的介绍 文档内容以及大致翻…

ROS笔记之kill掉所有ros节点rosnode

ROS笔记之kill掉所有ros节点rosnode 文章目录 ROS笔记之kill掉所有ros节点rosnode1. 杀死所有 ROS 节点&#xff08;不包括 rosmaster&#xff09;2. 杀死 rosmaster3. 验证所有节点和 rosmaster 是否已终止4. roscore 和 rosmaster 是同一个概念吗&#xff1f;5. 为什么执行 k…

【踩坑日记36】ModuleNotFoundError: No module named ‘taming‘

问题描述 ModuleNotFoundError: No module named ‘taming‘问题分析 未正确安装taming-transformers包 问题解决 从github网站中安装taming-transformers包&#xff1a; 从github网站中下载taming-transformers代码 git clone https://github.com/CompVis/taming-transfo…

微机原理与接口技术知识点总结——绪论

1.1、计算机发展概述 早期计算机的用途主要是用于算数&#xff0c;一直到20世纪电子领域基础研究的突破&#xff0c;也就是电子计算机的诞生&#xff0c;计算机才变得如此广泛。以微电子技术为基础制造的电子计算机已经完全取代了机械计算机和机电计算机&#xff0c;因此电子计…