电子计算器--课后程序(Python程序开发案例教程-黑马程序员编著-第12章-课后作业)
创始人
2025-05-28 04:27:10
0

实例2:电子计算器

从早期的算盘、算筹到如今的计算器,计算工具的不断升级使得人类的计算能力从速度与计算位数上都得到了质的提升。随着智能设备的发展,计算器从一个独立的机器成为了电子设备中的一个附加功能。一个常规的电子计算器如图1所示。

 

  1. 电子计算器

图1所示的电子计算器不仅支持“+”、“-”、“*”、“/”运算,还支持“回退”、“清空”与“退出”功能。本实例要求使用tkinter实现如图1所示的电子计算器。

实例目标

  1. 掌握tkinter基础组件的使用
  2. 熟练地创建菜单组件

实例分析

电子计算器的界面主要包含以下元素:

  1. 根窗口:大小不可拉伸。
  2. 窗口标题:内容为计算器。
  3. 顶级菜单:只包含“菜单”选项。
  4. 下拉菜单:只包含“退出”选项。
  5. 文本框:可同时接收键盘输入和按钮输入。
  6. 回退与清空按钮:两者占据一整行,大小相同。
  7. 16个按钮:所有的数字、小数点与运算符号。

由于回退和清空按钮的样式相同,其它按钮的样式相同,为了将相关组件使用框架统一管理,因此这里可创建两个框架分组排布组件。

文本框中的数据是一个字符串,它里面只能包含小数、整数、运算符,且是不可变的,因此这里需要先将字符串转换成列表,再将列表转换为字符串进行返回。

代码实现

(1)由于实例中需创建两个框架,这里可将这两个框架共有的属性作为函数的默认值,以简化创建框架的过程。定义一个创建框架的函数frame(),具体代码如下。

from tkinter import *

def frame(master):

    """将共同的属性作为默认值, 以简化Frame创建过程"""

    w = Frame(master)

    w.pack(side=TOP, expand=YES, fill=BOTH)

    return w

(2)界面中也包含多个按钮组件,同样可以提取这些组件共有的属性作为函数的默认值,以简化创建按钮的过程。定义一个创建按钮的函数btn(),具体代码如下。

def btn(master, text, command):

    """提取共同的属性作为默认值, 使Button创建过程简化"""

    w = Button(master, text=text, command=command, width=6)

    w.pack(side=LEFT, expand=YES, fill=BOTH, padx=2, pady=2)

    return w

(3)定义一个根据文本框内容计算的函数calc(),该函数中会尝试捕获处理文本框中的字符串:若separator_flag等于0,则调用del_separator()函数删除千位分隔符,否则调用add_separator()函数添加千位分隔符。一旦出现SyntaxError、ZeroDivisionError、NameError中的任一种异常便会在文本框中返回“Error”,具体代码如下。

def calc(text_data):

    """用eval方法计算表达式字符串"""

    try:

        if (separator_flag.get() == 0):

            return eval(del_separator(text_data))

        else:

            return add_separator(str(eval(del_separator(text_data))))

    except (SyntaxError, ZeroDivisionError, NameError):

        return 'Error'

(4)定义一个删除文本框中末尾字符的函数back(),该函数中需接收文本框中的字符串,返回删除末尾字符后的字符串,具体代码如下。

def back(text_data):

    """将text_data最末的字符删除并返回"""

    if len(text_data) > 0:

        return text_data[:-1]

    else:

        return text_data

(5)定义一个添加千位分隔符的函数add_separator(),该函数中需接收字符串,先获取该字符串中小数点所在的位置,并依据不同的位置将小数点之前与之后的字符分隔为两部分text_head与text_tail,然后为text_head插入千位分隔符,并将插入分隔符之后的text_head与text_tail合并转换成新的字符串返回,具体代码如下。

def add_separator(text_data):

    """向参数传入的数字串中添加千位分隔符

    这里考虑了三种情况: 无整数部份, 无小数部份, 同时有整数和小数部份

    由于字符串是不可改变的, 这里由字符串生成列表以便执行insert操作和

    extend操作, 操作完成后最由列表生成字符串返回

    """

    dot_index = text_data.find('.')

    if dot_index > 0:

        text_head = text[:dot_index]

        text_tail = text[dot_index:]

    elif dot_index < 0:

        text_head = text_data

        text_tail = ''

    else:

        text_head = ''

        text_tail = text_data

    list_ = [char for char in text_head]

    length = len(list_)

    tmp_index = 3

    while length - tmp_index > 0:

        list_.insert(length - tmp_index, ',')

        tmp_index += 3

    list_.extend(text_tail)

    new_text = ''

    for char in list_:

        new_text += char

    return new_text

(6)定义一个删除千位分隔符的函数del_separator (),具体代码如下。

def del_separator(text_data):

    """删除数字串中所有的千位分隔符"""

    return text_data.replace(',', '')

(7)创建根窗口,然后往根窗口中逐个添加界面元素,具体代码如下。

# 开始界面的实现

init_root = Tk()

init_root.resizable(width=False, height=False)

init_root.title("计算器")    # 添加标题

main_menus = Menu()          # 创建最上层主菜单

# 创建计算器菜单, 并加入到主菜单

calc_menu = Menu(main_menus, tearoff=0)

calc_menu.add_command(label='退出', command=lambda: exit())

main_menus.add_cascade(label='菜单', menu=calc_menu)

text = StringVar()

separator_flag = IntVar()

separator_flag.set(0)

view_menu = Menu(main_menus, tearoff=0)

init_root['menu'] = main_menus  # 将主菜单与root绑定

# 创建文本框

Entry(init_root, textvariable=text).pack(expand=YES,

fill=BOTH, padx=2, pady=4)

# 创建第一行三个按钮

first_line = frame(init_root)

btn(first_line, '回退', lambda t=text: t.set(back(t.get())))

btn(first_line, '清空', lambda t=text: t.set(''))

# 每行四个, 创建其余四行按钮

for key in ('789/', '456*', '123-', '0.=+'):

    others = frame(init_root)

    for char in key:

        if char == '=':

            btn(others, char,

                lambda data=text: data.set(calc(data.get())))

        else:

            btn(others, char,

                lambda data=text, c=char: data.set(data.get() + c))

(8)通过根窗口调用mainloop()函数监听事件循环,具体代码如下。

if __name__ == '__main__':

    init_root.mainloop()

代码测试

运行程序,在弹出的计算器的输入框中输入“11+22-33”,单击“=”按钮之前与之后的界面如图2所示。

  

  1. 电子计算器-计算

在图2中的输入框中输入“10/0”, 单击“=”按钮之前与之后的界面如图3所示。

  

  1. 电子计算器-错误

相关内容

热门资讯

安卓系统自带的网页,功能与特色... 你有没有发现,每次打开安卓手机,那熟悉的系统界面里总有一个默默无闻的小家伙——安卓系统自带的网页浏览...
美咖云系统安卓版,开启智能生活... 你有没有发现,最近手机上多了一个叫“美咖云系统安卓版”的小家伙?它就像一个魔法师,轻轻一点,就能让你...
安卓系统推荐最好的手机,盘点性... 你有没有想过,拥有一部性能卓越的手机,就像是拥有了移动的宝藏库?在这个信息爆炸的时代,一部好手机不仅...
安卓11系统能精简吗,释放潜能 你有没有发现,随着手机越来越智能,系统也越来越庞大?安卓11系统,这个最新的操作系统,是不是也让你觉...
安卓自动重启系统软件,揭秘原因... 手机突然自动重启,是不是感觉整个人都不好了?别急,今天就来和你聊聊这个让人头疼的安卓自动重启系统软件...
苹果手机x刷安卓系统,探索安卓... 你有没有想过,你的苹果手机X竟然也能刷上安卓系统?是的,你没听错,就是那个一直以来都和我们苹果手机X...
安卓系统智商低吗,智商低下的真... 你有没有想过,为什么安卓系统的智商总被调侃得好像有点低呢?是不是觉得它总是慢吞吞的,有时候还犯点小错...
安卓系统手机联系人,揭秘你的社... 你有没有发现,手机里的联系人列表就像是一个小小的社交圈呢?里面藏着我们的亲朋好友、工作伙伴,甚至还有...
安卓系统免费铃声下载,打造个性... 手机里那首老掉牙的铃声是不是让你觉得有点out了呢?别急,今天就来给你支个招,让你轻松给安卓手机换上...
安卓系统用哪个桌面好,打造个性... 你有没有发现,手机桌面可是我们每天都要面对的“脸面”呢?换一个好看的桌面,心情都能跟着好起来。那么,...
虚拟大师是安卓10系统,功能与... 你知道吗?最近在手机圈里,有个新玩意儿引起了不小的轰动,那就是虚拟大师!而且,更让人惊喜的是,这个虚...
安卓系统与苹果优缺点,系统优缺... 说到手机操作系统,安卓和苹果绝对是两大巨头,它们各有各的特色,就像两道不同的美味佳肴,让人难以抉择。...
安卓win双系统主板,融合与创... 你有没有想过,一台电脑如果既能流畅运行安卓系统,又能轻松驾驭Windows系统,那该有多爽啊?没错,...
安卓系统可精简软件,轻松提升手... 你有没有发现,手机里的安卓系统越来越庞大,软件也越装越多,有时候感觉手机就像个“大肚子”,不仅运行速...
安卓系统基于linux的代码,... 你有没有想过,那个陪伴你每天刷抖音、玩游戏、办公的安卓系统,其实背后有着一套复杂的基于Linux的代...
苹果和安卓的拍照系统,谁更胜一... 你有没有发现,现在手机拍照已经成为我们生活中不可或缺的一部分呢?无论是记录生活的点滴,还是捕捉美丽的...
苹果和安卓系统不同吗,系统差异... 你有没有想过,为什么你的手机里装的是苹果的iOS系统,而朋友的手机却是安卓系统呢?这两种系统,看似都...
安卓系统有多少级,揭秘其多级架... 你有没有想过,那个陪伴我们日常生活的安卓系统,它其实有着丰富的层级结构呢?没错,就是那个让我们的手机...
华为鸿蒙系统与安卓的,技术融合... 你知道吗?最近科技圈可是炸开了锅,华为鸿蒙系统与安卓的较量成为了大家热议的话题。这不,今天我就来给你...
什么安卓手机是苹果系统,搭载苹... 你有没有想过,为什么有些人宁愿花大价钱买苹果手机,而有些人却对安卓手机情有独钟呢?其实,这个问题背后...