Tkinter实战——简易计算器

本次任务主旨在于对Tkinter进行UI编程练习,不关注计算器的算法细节。

所以计算器实现是直接将输入的表达式用eval()函数传入编译,得到答案。

具体实现过程:

#创建窗口

创建一个340x720固定大小,标题为”计算器“的窗口

from tkinter import *

root = Tk()  #创造窗口
root.title("计算器")  #更改标题
root.resizable(0,0)   #窗口大小不可更改
root.geometry("340x720")  #窗口大小

mainloop()

#增加按键

接下来把设计好的Button添加进去

我设计了18个Button,10个数字,4个运算符号(+,-,*,/),1个小数点,1个等号,1个清屏键和1个删除输入键。

具体来看看Button()函数:

    第一个参数是窗口名字,即我们创建的root窗口

    之后是text,表示Button上显示的文字

    place()中包含Button的位置(以窗口左上角为原点,水平向右x轴,竖直向下y轴)和长宽

每个Button的位置就根据自己设计的界面大小和Button大小计算出即可

from tkinter import *

root = Tk()  #创造窗口
root.title("计算器")  #更改标题
root.resizable(0,0)   #窗口大小不可更改
root.geometry("340x720")  #窗口大小
#R0
But_cmp=Button(root,text='=').place(x=100,y=620,width=240,height=100)
But_point=Button(root,text='AC').place(y=620,width=100,height=100)
#R1
But_AC=Button(root,text='.').place(x=0,y=620-1*80,width=80,height=80)
But0=Button(root,text='0').place(x=0+1*80,y=620-1*80,width=80,height=80)
But_back=Button(root,text='<--').place(x=0+2*80,y=620-1*80,width=80,height=80)
But_division=Button(root,text='/').place(x=0+3*80,y=620-1*80,width=100,height=80)
#R2
But1=Button(root,text='1').place(x=0,y=620-2*80,width=80,height=80)  
But2=Button(root,text='2').place(x=0+1*80,y=620-2*80,width=80,height=80)
But3=Button(root,text='3').place(x=0+2*80,y=620-2*80,width=80,height=80)
But_multi=Button(root,text='*').place(x=0+3*80,y=620-2*80,width=100,height=80)
#R3
But4=Button(root,text='4').place(x=0,y=620-3*80,width=80,height=80)
But5=Button(root,text='5').place(x=0+1*80,y=620-3*80,width=80,height=80)
But6=Button(root,text='6').place(x=0+2*80,y=620-3*80,width=80,height=80)
But_sub=Button(root,text='-').place(x=0+3*80,y=620-3*80,width=100,height=80)
#R4
But7=Button(root,text='7').place(x=0,y=620-4*80,width=80,height=80)
But8=Button(root,text='8').place(x=0+1*80,y=620-4*80,width=80,height=80)
But9=Button(root,text='9').place(x=0+2*80,y=620-4*80,width=80,height=80)
But_add=Button(root,text='+').place(x=0+3*80,y=620-4*80,width=100,height=80)
mainloop()

#美化Button

接下来可以使用Button()中的参数更改文字大小,背景颜色等等属性

有如下参数可选择

函数

描述

text

显示文本内容

command

指定Button的事件处理函数

compound

指定文本与图像的位置关系

bitmap

指定位图

focus_set

设置当前组件得到的焦点

master

代表了父窗口

bg

设置背景颜色

fg

设置前景颜色

font

设置字体大小

height

设置显示高度、如果未设置此项,其大小以适应内容标签

relief

指定外观装饰边界附近的标签,默认是平的,可以设置的参数;

flat、groove、raised、ridge、solid、sunken

width

设置显示宽度,如果未设置此项,其大小以适应内容标签

wraplength

将此选项设置为所需的数量限制每行的字符,数默认为0

state

设置组件状态;正常(normal),激活(active),禁用(disabled)

anchor

设置Button文本在控件上的显示位置

可用值:n(north),s(south),w(west),e(east),和ne,nw,se,sw

bd

设置Button的边框大小;bd(bordwidth)缺省为1或2个像素

textvariable

设置Button与textvariable属性

 

from tkinter import *

root = Tk()  #创造窗口
root.title("计算器")  #更改标题
root.resizable(0,0)   #窗口大小不可更改
root.geometry("340x720")  #窗口大小
#R0
But_cmp=Button(root,text='=',font = ('微软雅黑',20),bg='orange').place(x=100,y=620,width=240,height=100)
But_point=Button(root,text='AC',font = ('微软雅黑',20),bg='orange').place(y=620,width=100,height=100)
#R1
But_AC=Button(root,text='.',bg='orange',font = ('微软雅黑',15)).place(x=0,y=620-1*80,width=80,height=80)
But0=Button(root,text='0',bg='orange',font = ('微软雅黑',12)).place(x=0+1*80,y=620-1*80,width=80,height=80)
But_back=Button(root,text='<--',bg='orange',font = ('微软雅黑',15)).place(x=0+2*80,y=620-1*80,width=80,height=80)
But_division=Button(root,text='/',font = ('微软雅黑',15),bg=('#969696')).place(x=0+3*80,y=620-1*80,width=100,height=80)
#R2
But1=Button(root,text='1',bg='orange',font = ('微软雅黑',12)).place(x=0,y=620-2*80,width=80,height=80)  #command后直接跟需要参数的函数会报错
But2=Button(root,text='2',bg='orange',font = ('微软雅黑',12)).place(x=0+1*80,y=620-2*80,width=80,height=80)
But3=Button(root,text='3',bg='orange',font = ('微软雅黑',12)).place(x=0+2*80,y=620-2*80,width=80,height=80)
But_multi=Button(root,text='*',font = ('微软雅黑',15),bg=('#969696')).place(x=0+3*80,y=620-2*80,width=100,height=80)
#R3
But4=Button(root,text='4',bg='orange',font = ('微软雅黑',12)).place(x=0,y=620-3*80,width=80,height=80)
But5=Button(root,text='5',bg='orange',font = ('微软雅黑',12)).place(x=0+1*80,y=620-3*80,width=80,height=80)
But6=Button(root,text='6',bg='orange',font = ('微软雅黑',12)).place(x=0+2*80,y=620-3*80,width=80,height=80)
But_sub=Button(root,text='-',font = ('微软雅黑',15),bg=('#969696')).place(x=0+3*80,y=620-3*80,width=100,height=80)
#R4
But7=Button(root,text='7',bg='orange',font = ('微软雅黑',12)).place(x=0,y=620-4*80,width=80,height=80)
But8=Button(root,text='8',bg='orange',font = ('微软雅黑',12)).place(x=0+1*80,y=620-4*80,width=80,height=80)
But9=Button(root,text='9',bg='orange',font = ('微软雅黑',12)).place(x=0+2*80,y=620-4*80,width=80,height=80)
But_add=Button(root,text='+',font = ('微软雅黑',15),bg=('#969696')).place(x=0+3*80,y=620-4*80,width=100,height=80)

mainloop()

#输出面板

面板上数据需要保持实时的更新,这个使用Tkinter中的StringVar()可以实现

result = StringVar()
result.set('这里是result')
process = StringVar()
process.set('这是process')

我们创建StringVar()类型的两个参数result和process,其中result用于储存结果,process用于储存表达式

StringVar有get()和set()函数,get()为读取值,set()为赋值

将两个变量镶入Label中

Label(root,anchor = 'se',font = ('微软雅黑',30),textvariable = result).place(y=200,width=340,height=50)
Label(root,anchor = 'se',font = ('微软雅黑',20),textvariable = process).place(width=340,height=200)

这里用到的Label参数:

    anchor表示设置显示位置,s代表south,e代表east,se即我们在东南(右下)显示内容,同理还有‘n’, ‘s’, ‘e’, ‘w’, ‘nw’, ‘sw’, ‘se’, ‘ne’, ‘center’这些参数可选,默认为center

    font等功能同Button

加上面板之后:

from tkinter import *

root = Tk()  #创造窗口
root.title("计算器")  #更改标题
root.resizable(0,0)   #窗口大小不可更改
root.geometry("340x720")  #窗口大小

result = StringVar()
result.set('这里是result')
process = StringVar()
process.set('这里是process')
#R0
But_cmp=Button(root,text='=',font = ('微软雅黑',20),bg='orange').place(x=100,y=620,width=240,height=100)
But_point=Button(root,text='AC',font = ('微软雅黑',20),bg='orange').place(y=620,width=100,height=100)
#R1
But_AC=Button(root,text='.',bg='orange',font = ('微软雅黑',15)).place(x=0,y=620-1*80,width=80,height=80)
But0=Button(root,text='0',bg='orange',font = ('微软雅黑',12)).place(x=0+1*80,y=620-1*80,width=80,height=80)
But_back=Button(root,text='<--',bg='orange',font = ('微软雅黑',15)).place(x=0+2*80,y=620-1*80,width=80,height=80)
But_division=Button(root,text='/',font = ('微软雅黑',15),bg=('#969696')).place(x=0+3*80,y=620-1*80,width=100,height=80)
#R2
But1=Button(root,text='1',bg='orange',font = ('微软雅黑',12)).place(x=0,y=620-2*80,width=80,height=80)  #command后直接跟需要参数的函数会报错
But2=Button(root,text='2',bg='orange',font = ('微软雅黑',12)).place(x=0+1*80,y=620-2*80,width=80,height=80)
But3=Button(root,text='3',bg='orange',font = ('微软雅黑',12)).place(x=0+2*80,y=620-2*80,width=80,height=80)
But_multi=Button(root,text='*',font = ('微软雅黑',15),bg=('#969696')).place(x=0+3*80,y=620-2*80,width=100,height=80)
#R3
But4=Button(root,text='4',bg='orange',font = ('微软雅黑',12)).place(x=0,y=620-3*80,width=80,height=80)
But5=Button(root,text='5',bg='orange',font = ('微软雅黑',12)).place(x=0+1*80,y=620-3*80,width=80,height=80)
But6=Button(root,text='6',bg='orange',font = ('微软雅黑',12)).place(x=0+2*80,y=620-3*80,width=80,height=80)
But_sub=Button(root,text='-',font = ('微软雅黑',15),bg=('#969696')).place(x=0+3*80,y=620-3*80,width=100,height=80)
#R4
But7=Button(root,text='7',bg='orange',font = ('微软雅黑',12)).place(x=0,y=620-4*80,width=80,height=80)
But8=Button(root,text='8',bg='orange',font = ('微软雅黑',12)).place(x=0+1*80,y=620-4*80,width=80,height=80)
But9=Button(root,text='9',bg='orange',font = ('微软雅黑',12)).place(x=0+2*80,y=620-4*80,width=80,height=80)
But_add=Button(root,text='+',font = ('微软雅黑',15),bg=('#969696')).place(x=0+3*80,y=620-4*80,width=100,height=80)
Label(root,anchor = 'se',font = ('微软雅黑',30),textvariable = result).place(y=200,width=340,height=50)
Label(root,anchor = 'se',font = ('微软雅黑',20),textvariable = process).place(width=340,height=200)

mainloop()

#运算功能实现

我们已经完成了整个面板的制作,最后就是面板背后,实现具体按键的功能了

算法很简单,将所有的输入传入到eval(),让编译器来运算,然后输出结果。

每按下一个按键,我们在Button中加入command参数,连接我们需要调用的函数,注意result和process是可以用来动态存储的,所以我们可以直接将表达式的输入储存在result中(第二个显示面板),在完成输入点击’=‘后,将整个result传入eval()得到结果即可。

注意一点,如果结果是无限小数(如1/3),面板会不够大,所以我采取保留六位小数的操作

    if isinstance(ans,float):
        ans=round(ans,6)

意为如果答案是float类型,则只保留6位小数

剩下的就是一些小细节的东西

如可以每次输入前检测面板目前的内容,如果为空可以显示善意的提示语句

如在一次运算完后,可以设定一个Flag用于标记,下次输入时清除面板数据,防止错误

......

#完整代码

from tkinter import *

root = Tk()  #创造窗口
root.title("计算器")  #更改标题
root.resizable(0,0)   #窗口大小不可更改
root.geometry("340x720")  #窗口大小

result = StringVar()
result.set('输入表达式...')
process = StringVar()
process.set('')
#R0
But_cmp=Button(root,text='=',font = ('微软雅黑',20),bg='orange',command=lambda:comput()).place(x=100,y=620,width=240,height=100)
But_point=Button(root,text='AC',font = ('微软雅黑',20),bg='orange',command=lambda:press('AC')).place(y=620,width=100,height=100)
#R1
But_AC=Button(root,text='.',bg='orange',font = ('微软雅黑',15),command=lambda:press('.')).place(x=0,y=620-1*80,width=80,height=80)
But0=Button(root,text='0',bg='orange',font = ('微软雅黑',12),command=lambda:press('0')).place(x=0+1*80,y=620-1*80,width=80,height=80)
But_back=Button(root,text='<--',bg='orange',font = ('微软雅黑',15),command=lambda:press('b')).place(x=0+2*80,y=620-1*80,width=80,height=80)
But_division=Button(root,text='/',font = ('微软雅黑',15),bg=('#969696'),command=lambda:press('/')).place(x=0+3*80,y=620-1*80,width=100,height=80)
#R2
But1=Button(root,text='1',bg='orange',font = ('微软雅黑',12),command=lambda:press('1')).place(x=0,y=620-2*80,width=80,height=80)  #command后直接跟需要参数的函数会报错
But2=Button(root,text='2',bg='orange',font = ('微软雅黑',12),command=lambda:press('2')).place(x=0+1*80,y=620-2*80,width=80,height=80)
But3=Button(root,text='3',bg='orange',font = ('微软雅黑',12),command=lambda:press('3')).place(x=0+2*80,y=620-2*80,width=80,height=80)
But_multi=Button(root,text='*',font = ('微软雅黑',15),bg=('#969696'),command=lambda:press('*')).place(x=0+3*80,y=620-2*80,width=100,height=80)
#R3
But4=Button(root,text='4',bg='orange',font = ('微软雅黑',12),command=lambda:press('4')).place(x=0,y=620-3*80,width=80,height=80)
But5=Button(root,text='5',bg='orange',font = ('微软雅黑',12),command=lambda:press('5')).place(x=0+1*80,y=620-3*80,width=80,height=80)
But6=Button(root,text='6',bg='orange',font = ('微软雅黑',12),command=lambda:press('6')).place(x=0+2*80,y=620-3*80,width=80,height=80)
But_sub=Button(root,text='-',font = ('微软雅黑',15),bg=('#969696'),command=lambda:press('-')).place(x=0+3*80,y=620-3*80,width=100,height=80)
#R4
But7=Button(root,text='7',bg='orange',font = ('微软雅黑',12),command=lambda:press('7')).place(x=0,y=620-4*80,width=80,height=80)
But8=Button(root,text='8',bg='orange',font = ('微软雅黑',12),command=lambda:press('8')).place(x=0+1*80,y=620-4*80,width=80,height=80)
But9=Button(root,text='9',bg='orange',font = ('微软雅黑',12),command=lambda:press('9')).place(x=0+2*80,y=620-4*80,width=80,height=80)
But_add=Button(root,text='+',font = ('微软雅黑',15),bg=('#969696'),command=lambda:press('+')).place(x=0+3*80,y=620-4*80,width=100,height=80)
Label(root,anchor = 'se',font = ('微软雅黑',30),textvariable = result).place(y=200,width=340,height=50)
Label(root,anchor = 'se',font = ('微软雅黑',20),textvariable = process).place(width=340,height=200)
Flag = 0
def press(x):
    global Flag
    if Flag:  #刚完成上一次运算,面板全部清除
        result.set("输入表达式...")
        process.set('')
        Flag=0
    if x == 'AC': #面板清除
        if result.get() == "输入表达式...":
            return
        result.set("输入表达式...")
        process.set('')
        return
    if x == 'b':  #退位
        if result.get() == "输入表达式...":
            return
        temp=result.get()[0:-1]  #切片操作,保留面板字符串中下标0到倒数第二位(-1)的内容
        if temp=='':
            result.set('输入表达式...')
        else:
            result.set(temp)
        return
    if result.get()!='输入表达式...':
        result.set(result.get()+x)
    else:
        result.set(x)
def comput():
    expression = result.get()
    ans = eval(expression)
    process.set(expression+"=")
    if isinstance(ans,float):  #如果为小数,保留6位
        ans=round(ans,6)
    result.set(ans)
    global Flag
    Flag = 1  #标记完成了一次运算

mainloop()

#效果图

好的,以下是一个使用tkinter库编写的简易计算器的示例代码: ```python import tkinter as tk class Calculator: def __init__(self, master): self.master = master master.title("简易计算器") # 创建输入框 self.entry = tk.Entry(master, width=30, justify="right") self.entry.grid(row=0, column=0, columnspan=4, padx=5, pady=5) # 定义数字按钮 numbers = ["7", "8", "9", "4", "5", "6", "1", "2", "3", "0"] # 创建数字按钮 for i, number in enumerate(numbers): button = tk.Button(master, text=number, width=7, height=3, command=lambda num=number: self.click(num)) button.grid(row=i//3+1, column=i%3, padx=5, pady=5) # 创建运算符按钮 operators = ["+", "-", "*", "/", "C", "=", "(", ")"] for i, operator in enumerate(operators): button = tk.Button(master, text=operator, width=7, height=3, command=lambda op=operator: self.click(op)) button.grid(row=i//2+1, column=i%2+3, padx=5, pady=5) def click(self, key): if key == "C": self.entry.delete(0, tk.END) elif key == "=": try: result = eval(self.entry.get()) self.entry.delete(0, tk.END) self.entry.insert(0, result) except: self.entry.delete(0, tk.END) self.entry.insert(0, "错误") else: self.entry.insert(tk.END, key) root = tk.Tk() my_calculator = Calculator(root) root.mainloop() ``` 这个示例代码创建了一个名为Calculator的类,它继承自tkinter的Frame类。类的构造函数中创建了一个输入框和数字、运算符按钮,并为每个按钮添加了响应函数。在响应函数中,当用户按下数字或运算符按钮时,会向输入框中插入相应的数字或运算符;当用户按下“C”清除按钮时,会清空输入框;当用户按下“=”等于按钮时,会计算输入框中的表达式并显示结果,如果计算过程中出现错误,则在输入框中显示“错误”。 你可以将这段代码保存为一个.py文件并运行它,就可以看到一个简单的计算器界面。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值