实践: 使用tkinter实现的计算器

使用tkinter实现的计算器

#!/usr/bin/env pythonright

-- coding: UTF-8 --

#使用tkinter模块实现一个简单的加减乘除计算器

import tkinter as tk
import functools

#常量
maxLen = 40
operator = ('/','*','-','+') #计算符号


class calcuatorApp(tk.Frame):
	#保存计算式内容(由于计算式长度有可能超过能够表示的最大长度,所以需要另外保存)
	processTextBack = ''

	def __init__(self, master=None):
		super().__init__(master)
		self.processTextBack = ''
		self.grid(padx=25, pady=25,sticky=tk.NSEW)
		self.create_widgets()  #生成窗口上的显示区域和按钮

	def create_widgets(self):
		#app随着外层窗口缩放
		top=self.winfo_toplevel()
		top.rowconfigure(0, weight=1)
		top.columnconfigure(0, weight=1)
		# 7行4列的各个组件随着app的大小缩放
		for i in range(7):      #7行自动缩放
			self.rowconfigure(i, weight=1)
		for i in range(4):      #4列自动缩放
			self.columnconfigure(i, weight=1)
		#按钮上显示的字符
		textForBtn = (('C','(',')','%'),   #%为百分号
					  ('7','8','9','/'),
					  ('4','5','6','*'),
					  ('1','2','3','-'),
					  ('0','.','=','+'))

		#界面上第一行用于输出计算式
		self.process = tk.Label(self,text='',font='courier 15',bg='#DCDCDC',anchor = 'e')
		self.process.grid(row=0, columnspan=4, padx=1, pady=1, ipadx=200, ipady=10, sticky=tk.NSEW)

		#界面上第二行用于输出计算结果
		self.result = tk.Label(self,text='',font='courier 15 bold',bg='#DCDCDC',anchor = 'e')
		self.result.grid(row=1, columnspan=4, padx=1, pady=1, ipadx=200, ipady=10, sticky=tk.NSEW)

		#界面上第三行开始用于显示0-9的数字和计算符号
		for i in range(5):      #5行
			for j in range(4):  #4列
				tempbtn = tk.Button(self,text=textForBtn[i][j],font='courier 15',bg='#DCDCDC')
				#点击=按钮(计算)
				if(textForBtn[i][j] == '='):
					tempbtn['command'] = self.equals
				#点击C按钮(清空)
				elif(textForBtn[i][j] == 'C'):
					tempbtn['command'] = functools.partial(self.inputClear)
				else:
				#其他
					tempbtn['command'] = functools.partial(self.inputText,tempbtn)
				tempbtn.grid(row=i+2, column=j, padx=1, pady=1, ipadx=50, ipady=10, sticky=tk.NSEW)

	# 点击C按钮,清空
	def inputClear(self):
		self.processTextBack=''
		self.process['text']=''
		self.result['text']=''

	# 点击=按钮,进行计算
	def equals(self):
		#获取计算式
		processText = self.processTextBack

		#检查计算式: 计算式长度为空,=无效
		if(len(processText) == 0): 
			return
		#检查计算式: 计算式最后一个为=,=重复无效
		if(processText[-1] == '='): 
			return
		#检查计算式: 计算式最后一个为(,报错
		if(processText[-1] == '('): 
			self.result['text']= 'Input Error'
			return
		#检查计算式:操作数不足报错
		if(processText[-1] in '+-/*'): 
			self.result['text']= 'Input Error'
			return
		#)不足的话,自动补齐
		countLeft = processText.count('(')
		countRight = processText.count(')')
		if(countLeft > 0 and  countLeft > countRight):
			processText += ')' * (countLeft - countRight)
		#计算用的字符串里面百分号%替换成/100  (要保证%的优先级)
		processForEval = processText
		sIndex = 0
		while('%' in processForEval):
                    	#开始查找%,切分成左右两边
                    	Index1 =  processForEval.find('%')
                   		strLeft = processForEval[:Index1]
                    	strRight = processForEval[Index1+1:]
                    	#%的前一位为数字:  操作数% 变成 (操作数/100)
                   		if(strLeft[-1].isdigit()):
                            	#%左边字符串的最后一个操作数
                            	strTmp = self.operandLast(strLeft)
                            	strLeft = strLeft[0:len(strLeft) - len(strTmp)] + '('+ strTmp +'/100)'
                    	else:
                    	#%的前一位为): (操作数1 + 操作数2)%  变成((操作数1 + 操作数2)/100)
                            	indexTmp = strLeft.rfind('(')
                            	if(indexTmp == -1):
                                   		indexTmp = 0
                            	strLeft = strLeft[:indexTmp] + '(' + strLeft[indexTmp:] + '/100)'
                    	processForEval = strLeft + strRight
		#计算
		try:
			result = str(eval(processForEval))
		except:
			result = 'Input Error'
		#表示计算式和结果
		self.processTextBack = processText + '='
		self.process['text']=  processText + '='
		self.result['text']= result

	# 点击=,C以外的其他按钮
	def inputText(self, btn):
		#按钮名称
		btnname = btn['text']
		resultClearFlg = False
		resultText = self.result['text']
		#计算式内容确认
		processText = self.processTextBack
		if(len(processText) > 0 and processText[-1] == '='):  #如果计算式以=结尾,则清空既存计算式和结果
			processText = ''
			resultClearFlg = True
		#根据按钮名称进行相应判定
		chkflg = True
		if(btnname.isdigit()):
			#数字按钮,  前面不能为),%
			if(len(processText) > 0 and  processText[-1] in (')','%') ):
				chkflg = False
		elif( btnname == '.' ):
			#小数点按钮,  前面不能为),%,.
			if(len(processText) > 0 and  processText[-1] in (')','%','.') ):
				chkflg = False
			#一个操作数里面不能出现两个(例如:2.33.5)
			if(chkflg and processText.rfind('.') > -1):
				operand = self.operandLast(processText)
				if('.' in operand):
					chkflg = False
		elif( btnname == '(' ):
			#左括号按钮, 前面只能为空,操作符,(
			if(len(processText)>0 and not (processText[-1] in operator or processText[-1] =='(')):
				chkflg = False
		elif( btnname == ')' ):
			#右括号按钮, 前面只能为数字或者%
			if(len(processText) == 0): #前面空白
				chkflg = False
			elif(not (processText[-1].isdigit() or processText[-1]=='%')):  #前面不为数字,%
				chkflg = False
			else:
				#判定前面是否有对应的(
				if(processText.count('(') <= processText.count(')')):
					chkflg = False
		elif( btnname == '%' ):
			#百分号按钮,前面必须为()包含的计算式或者数字
			if(len(processText) == 0): #前面空白
				chkflg = False
			elif(not(processText[-1].isdigit() or processText[-1]==')')):  #前面必须为()包含的计算式或者数字
				chkflg = False
		else:
			#'/''*''+''-'计算符号
			#前一次计算完毕,下一次从计算符号开始的话,把结果作为计算式的开头
			if(resultClearFlg):
				processText = resultText
			if(len(processText) == 0): #前面空白
				chkflg = False
			elif(processText[-1] in operator or processText[-1]=='('): #前面不能为(和计算符号
				chkflg = False

		#判定为True时候,计算式内容显示
		if (chkflg):
			if( btnname == '.'):
				#前一位不是数字的时候,自动补0
				if (len(processText) == 0 or (len(processText) > 1 and  not(processText[-1].isdigit()))):
					strTmp = processText + '0' +  btnname
				else:
					strTmp = processText + btnname
			else:
				strTmp = processText + btnname
			#长度超出之后左边的截断后显示
			self.processTextBack =  strTmp #长度不截断
			self.process['text'] =  strTmp if len(strTmp) < maxLen else strTmp[-maxLen:]
			if(resultClearFlg):
				self.result['text'] = ''

	#取得计算式的最后一个操作数
	def operandLast(self, text):
		#text长度为0
		if(len(text) == 0):
			return ''
		#最后一个计算符的位置
		position = max([text.rfind(item) for item in operator])
		#最后一个字符为计算符
		if(position == len(text) -1 ):
			return ''
		#没有找到计算符,整个作为一个操作数
		if(position == -1):
			return text
		else:
			return text[position+1:]

if __name__ == '__main__':
	#主窗口
	myWindow = tk.Tk()
	myWindow.title('计算器')     #标题
	myWindow.geometry('600x400') #初始尺寸
	myWindow.config(background ='#FFFFF0') #颜色

	#在主窗口创建一个计算器frame
	myCalcuatorApp = calcuatorApp(master=myWindow)
	myCalcuatorApp.master.minsize(600,400) #最小尺寸
	myCalcuatorApp.master.maxsize(900,600) #最大尺寸
	myCalcuatorApp.config(background ='#FFFFF0') #颜色

	#消息循环
	myWindow.mainloop()

运行结果:
在这里插入图片描述

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是使用tkinter实现计算器界面的Python代码: ```python import tkinter as tk class Calculator: def __init__(self, master): self.master = master master.title("Calculator") # 创建显示屏 self.screen = tk.Entry(master, width=25, font=('Arial', 16)) self.screen.grid(row=0, column=0, columnspan=4, padx=5, pady=5) # 创建按钮 self.create_button("7", 1, 0) self.create_button("8", 1, 1) self.create_button("9", 1, 2) self.create_button("/", 1, 3) self.create_button("4", 2, 0) self.create_button("5", 2, 1) self.create_button("6", 2, 2) self.create_button("*", 2, 3) self.create_button("1", 3, 0) self.create_button("2", 3, 1) self.create_button("3", 3, 2) self.create_button("-", 3, 3) self.create_button("0", 4, 0) self.create_button(".", 4, 1) self.create_button("C", 4, 2) self.create_button("+", 4, 3) self.create_button("=", 5, 0, columnspan=4) def create_button(self, text, row, column, columnspan=1): button = tk.Button(self.master, text=text, width=5, height=2, font=('Arial', 16), command=lambda: self.button_click(text)) button.grid(row=row, column=column, columnspan=columnspan, padx=5, pady=5) def button_click(self, text): if text == "=": try: result = eval(self.screen.get()) self.screen.delete(0, tk.END) self.screen.insert(0, str(result)) except: self.screen.delete(0, tk.END) self.screen.insert(0, "Error") elif text == "C": self.screen.delete(0, tk.END) else: self.screen.insert(tk.END, text) root = tk.Tk() calculator = Calculator(root) root.mainloop() ``` 以上代码创建了一个名为Calculator的类,其中包含了创建显示屏和按钮的方法。在button_click方法中,我们使用eval函数计算表达式的结果,并将结果显示在显示屏上。如果表达式无法计算,我们将显示“Error”消息。 我们在主函数中创建一个Tkinter窗口并实例化Calculator类。最后,我们通过调用主循环方法让程序进入事件循环,开始监听并响应用户输入。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值