前言
此文章中使用了 中自带的
库来实现一个计算器。与普通计算器不同的是,我们要实现的计算机支持诸如
这样含有多个符号和
这样含有括号的式子。
先让大家浏览一下最终结果。
正文
首先我们需要引入 库。使用通配符
可以便捷地使用其中的内容。
from tkinter import *
然后我们写一个窗口类,以 的
为父类,并初始化相关参数。
class TK(Tk):
def __init__(self):
super().__init__(className='计算器');
self.geometry('250x250')
self.resizable(0,0)
然后我们需要使用 (滚动文本框)类以显示式子,需要先导入。
from tkinter.scrolledtext import ScrolledText as stext
然后对其进行初始化。
f1=Frame(self) # 将文本框放入一个Frame里,防止与下面的按钮产生布局冲突
self.sc = stext(f1, height=3, state='disabled') # state初始化为不可用,防止用户自主输入
self.sc.pack()
接下来我们写按钮。先实现数字、小数点、括号和运算符号键,因为它们的工作只是往文本框内添加内容,相对简单、套路。
f2=Frame(self)
# 将按钮的父类设为一个Frame并使用grid网格化布局,防止与文本框的pack冲突
Button(f2, text='7', width=5, height=2, command=lambda: self.insert('7')).grid(row=0, column=0)
Button(f2, text='8', width=5, height=2, command=lambda: self.insert('8')).grid(row=0, column=1)
Button(f2, text='9', width=5, height=2, command=lambda: self.insert('9')).grid(row=0, column=2)
Button(f2, text='4', width=5, height=2, command=lambda: self.insert('4')).grid(row=1, column=0)
Button(f2, text='5', width=5, height=2, command=lambda: self.insert('5')).grid(row=1, column=1)
Button(f2, text='6', width=5, height=2, command=lambda: self.insert('6')).grid(row=1, column=2)
Button(f2, text='(', width=5, height=2, command=lambda: self.insert('(')).grid(row=1, column=3)
Button(f2, text=')', width=5, height=2, command=lambda: self.insert(')')).grid(row=1, column=4)
Button(f2, text='1', width=5, height=2, command=lambda: self.insert('1')).grid(row=2, column=0)
Button(f2, text='2', width=5, height=2, command=lambda: self.insert('2')).grid(row=2, column=1)
Button(f2, text='3', width=5, height=2, command=lambda: self.insert('3')).grid(row=2, column=2)
Button(f2, text='+', width=5, height=2, command=lambda: self.insert('+')).grid(row=2, column=3)
Button(f2, text='-', width=5, height=2, command=lambda: self.insert('-')).grid(row=2, column=4)
Button(f2, text='0', width=5, height=2, command=lambda: self.insert('0')).grid(row=3, column=0)
Button(f2, text='.', width=5, height=2, command=lambda: self.insert('.')).grid(row=3, column=1)
Button(f2, text='×', width=5, height=2, command=lambda: self.insert('×')).grid(row=3, column=3)
Button(f2, text='÷', width=5, height=2, command=lambda: self.insert('÷')).grid(row=3, column=4)
对应的 函数如下。
def insert(self,char):
self.sc.config(state='normal') # 先将文本框设为可用
self.sc.insert(END,char) # 加入字符
self.sc.config(state='disabled') # 再将其设为不可用
剩下的就是一些功能按键了,先实现 (即清空)键。
Button(f2, text='CE', width=5, height=2, command=self.CE).grid(row=0, column=3)
对应的 函数如下。
def CE(self):
self.sc.config(state='normal')
self.sc.delete('1.0',END) # 文本框的删除操作,不懂的可以去学学
self.sc.config(state='disabled')
然后是 ->(即backspace)键。
Button(f2, text='->', width=5, height=2, command=self.backspace).grid(row=0, column=4)
对应的 函数如下。
def backspace(self):
self.sc.config(state='normal')
self.sc.delete('end - 2 chars','end - 1 char') # 删除末尾一个字符
self.sc.config(state='disabled')
最后是 (即结果)键。
Button(f2, text='=', width=5, height=2, command=self.get_res).grid(row=3, column=2)
键的 get_res 函数较为复杂。首先我们先将文本框内的内容取出来,再对其进行处理。因为计算机无法识别
和
,我们需将其转换为
和
。
def get_res(self):
self.sc.config(state='normal')
s=self.sc.get('1.0',END) # 获取文本框中的内容
s2=''
for i in s:
if i=='×':
s2+='*'
elif i=='÷':
s2+='/'
else:
s2+=i
然后,我们对 使用一个奇妙函数——
, 它可以处理表达式、算式。但如果式子错误,它就会报错。所以我们需要使用异常处理 try-except-finally 代码块。
try:
res=eval(s2) # 使用eval函数
self.CE() # 清空文本框
for i in str(res):
self.insert(i) # 将答案输入至文本框中
except:
showerror('错误','请检查算式是否正确。') # 如果错误,弹出错误提示框(需导入)
finally:
self.sc.config(state='disabled')
这样我们的计算器就写好了,在最后还要加上运行代码,将 类实例化。
总程序
以下是整合程序。
from tkinter import *
from tkinter.scrolledtext import ScrolledText as stext
from tkinter.messagebox import showerror
class TK(Tk):
def __init__(self):
super().__init__(className='计算器');
self.geometry('250x250')
self.resizable(0,0)
f1=Frame(self)
self.sc = stext(f1, height=3, state='disabled')
self.sc.pack()
f2=Frame(self)
Button(f2, text='7', width=5, height=2, command=lambda: self.insert('7')).grid(row=0, column=0)
Button(f2, text='8', width=5, height=2, command=lambda: self.insert('8')).grid(row=0, column=1)
Button(f2, text='9', width=5, height=2, command=lambda: self.insert('9')).grid(row=0, column=2)
Button(f2, text='4', width=5, height=2, command=lambda: self.insert('4')).grid(row=1, column=0)
Button(f2, text='5', width=5, height=2, command=lambda: self.insert('5')).grid(row=1, column=1)
Button(f2, text='6', width=5, height=2, command=lambda: self.insert('6')).grid(row=1, column=2)
Button(f2, text='(', width=5, height=2, command=lambda: self.insert('(')).grid(row=1, column=3)
Button(f2, text=')', width=5, height=2, command=lambda: self.insert(')')).grid(row=1, column=4)
Button(f2, text='1', width=5, height=2, command=lambda: self.insert('1')).grid(row=2, column=0)
Button(f2, text='2', width=5, height=2, command=lambda: self.insert('2')).grid(row=2, column=1)
Button(f2, text='3', width=5, height=2, command=lambda: self.insert('3')).grid(row=2, column=2)
Button(f2, text='+', width=5, height=2, command=lambda: self.insert('+')).grid(row=2, column=3)
Button(f2, text='-', width=5, height=2, command=lambda: self.insert('-')).grid(row=2, column=4)
Button(f2, text='0', width=5, height=2, command=lambda: self.insert('0')).grid(row=3, column=0)
Button(f2, text='.', width=5, height=2, command=lambda: self.insert('.')).grid(row=3, column=1)
Button(f2, text='×', width=5, height=2, command=lambda: self.insert('×')).grid(row=3, column=3)
Button(f2, text='÷', width=5, height=2, command=lambda: self.insert('÷')).grid(row=3, column=4)
Button(f2, text='CE', width=5, height=2, command=self.CE).grid(row=0, column=3)
Button(f2, text='->', width=5, height=2, command=self.backspace).grid(row=0, column=4)
Button(f2, text='=', width=5, height=2, command=self.get_res).grid(row=3, column=2)
f1.pack(); f2.pack()
def CE(self):
self.sc.config(state='normal')
self.sc.delete('1.0',END)
self.sc.config(state='disabled')
def backspace(self):
self.sc.config(state='normal')
self.sc.delete('end - 2 chars','end - 1 char')
self.sc.config(state='disabled')
def insert(self,char):
self.sc.config(state='normal')
self.sc.insert(END,char)
self.sc.config(state='disabled')
def get_res(self):
self.sc.config(state='normal')
s=self.sc.get('1.0',END)
s2=''
for i in s:
if i=='×':
s2+='*'
elif i=='÷':
s2+='/'
else:
s2+=i
try:
res=eval(s2)
self.CE()
for i in str(res):
self.insert(i)
except:
showerror('错误','请检查算式是否正确。')
finally:
self.sc.config(state='disabled')
if __name__=='__main__': # 运行
TK().mainloop() # 将TK实例化
制作不易,点个赞吧qaq