利用Tkinter(python3.6)实现一个简单计算器


Posted in Python onDecember 21, 2017

前言

上机实践课程开始了,嗯,老师来了之后念了下PPT,然后说:开始做吧.........

然后就开始了Python的GUI之路,以前没接触过PYthon的可视化界面(虽然这样很不明智)

但是现在做起来感觉写小工具还挺方便的,当时搜到的第一个库便是Tkinter就直接开始写了

后来发现QT很不错的样子,下个实验就用QT吧.然后关于Tkinter(python3.6)

计算器源码 ennn.....有的命名不规范.......

首先对于python中栈的实现是通过list的方式模拟

pop()出栈,append()入栈

首先我们来看一下常用的TKinter提供的核心小构件类:

小构件类 描述
Button 按钮
Canvas 结构化图形,用于绘制图形,创建图形编辑器以及实现自定义小构件类
Checkbutton 单击复选按钮在值之间切换
Entry 文本域或称文本框
Frame 容器(可包含其他的小构件)
Label 显示文本或图像
Menu 显示下拉菜单和弹出菜单的菜单栏
Menubutton 下拉菜单的菜单按钮
Message 类似于标签显示文本,但能自动将文本放在给定宽高内
Radiobutton 单选按钮
Text 格式化的文本显示,支持内嵌图片和文本,允许用不同风格和属性显示和编辑文本

开始一个窗口

做一个可视化的东西,首先想到的坑定是窗口吧

窗口又有很多构成,比如title,ico,size,bd,菜单等.

import tkinter
import os
from tkinter import *
class Calculator(object):
 """计算器"""
 def __init__(self):
 self.tk=tkinter.Tk() #实例化
 self.tk.title('计算器')
 self.tk.minsize(370,460)
 self.tk.maxsize(400,400)
 #也可以用self.tk.resizable(0, 0)来禁止调节大小
 self.tk.iconbitmap(os.getcwd()+'/favicon.ico')
 def start(self):
 self.tk.mainloop() 
if __name__ == '__main__':
 NewCalculator=Calculator()
 NewCalculator.start()

这里就生成了一个基本的窗口,对于其中的mainloop()的作用

如果我们删除它,窗口会一闪而过,它就是为了防止这种情况

面板显示

做成计算器之后坑定要先是计算结果,这里就需要生成显示面板

当然我们也会很自然地联想到显示内容的字体设置等需求,具体事例在下面代码

....
import tkinter.font as tkfont
....
 #字体设置
 self.EntryFont=tkfont.Font(self.tk,size=13)
 self.ButtonFont=tkfont.Font(self.tk,size=12)
 #面板显示
 self.count=tkinter.StringVar()
 self.count.set('0')
 self.label=tkinter.Label(self.tk,bg='#EEE9E9',bd='3',fg='black',anchor='center',font=self.EntryFont,textvariable=self.count)
 self.label.place(y=10,width=380,height=40)
....

其中tkinter中面板Lable有一些参数,这里用到的基本上也可以满足常见的需求了

其中bg是背景色,fg是前景色,改变内容的颜色,anchor是定位内容在面板中的位置,如下图

方向 示例 表格
nw n ne
w center e
sw s se

关于面板以及后边的Button的定位,可以用很多方式,place可以准确的定位,也可以用pack(),grid()

对于计算器place是更好的,能够准确定位每一个控件

其中字体也可以直接在Lable()加参数,例如font=("Arial,6")

textvariable相当于“监听”的作用,绑定tkinter中的string,就可以用set()的方式方便的改变面板的内容

按钮,输入框设置

按钮,输入框的参数和面板里面的是相似的

self.NumButton=tkinter.Button(master=self.tk,relief=GROOVE,bg='#EE6A50',text=self.ButtonList[0],
 font=self.ButtonFont,command=self.clear)
self.NumButton.place(x=30,y=80,width=70,height=55)
self.shiEntry=Entry(self.baoxianTk,validate='key',validatecommand=(self.checkNum,'%P'),font=self.EntryFont)
self.shiEntry.place(x=190,y=80)

一样的是通过bg等参数设置基础的样式,只不过这里会通过command绑定事件,类似于JQ中的.click

这里的place也是为了能够准确定位才使用的,其中的relief代表着Button的样式

relief=FLAT or GROOVE or RAISED or RIDGE or SOLID or SUNKEN

其中删除输入框的输入内容

text.delete(10) #删除索引值为10的值
text.delete(10, 20) #删除索引值从10到20之前的值
text.insert(0, END) #删除所有值

输入限制

在设计功能的时候我们可能需要用户输入数字等,这里可以进行限制一下

Button参数中validate指定什么时候执行validatecommand绑定的函数,使用%P可以实时获取输入的内容

当validate选项指定为key的时候,有任何的输入操作都会被拦截,这个时候返回True白能量才会输入到Entry

self.checkNum=self.baoxianTk.register(self.validateNum)
self.gerenEntry=Entry(self.baoxianTk,validate='key',validatecommand=(self.checkNum,'%P'),font=self.EntryFont)
self.gerenEntry.place(x=190,y=190)
#验证是否输入数字 
def validateNum(self,content):
 if content.isdigit() and int(content)>=0 or content=="":
 return True
 else:
 return False

validateNum()函数可以根据自己的需求进行更改

启用验证validate选项可以设置的值有:

名称 事件
focus 当 Entry 组件获得或失去焦点的时候验证
focusin 当 Entry 组件获得焦点的时候验证
focusout 当 Entry 组件失去焦点的时候验证
key 当输入框被编辑的时候验证
all 当出现上边任何一种情况的时候验证

拓展符号设计

这个小计算器中我增加了%,/,sqrt三个符号

对于他们的实现我的思路是添加到面板之前检测一下传入的button内容

如果是这三种符号则做出对应的处理

其中需要注意如果是多位数或者带有符号式子

不能直接进行变换,需要判断你要转置的数字的位数,我的具体方式如下

def checkList(self):
 result=0
 locate=-1
 listSum=0
 for length in range(0,len(self.inputlist)):
 if re.findall(r'[-+*/]',str(self.inputlist[length])):
 result=1
 if length>locate:
  locate=length
 else:
 pass
 if result==1:
 for i in range(locate+1,len(self.inputlist)):
 listSum+=int(self.inputlist[i])*(10**(len(self.inputlist)-i-1))
 else:
 for j in range(0,len(self.inputlist)):
 listSum+=int(self.inputlist[j])*(10**(len(self.inputlist)-j-1))
 return listSum,locate
 #添加button
 def addButton(self,button):
 if button==self.ButtonList[18]:
 listSum,locate=self.checkList()
 if locate==-1:
 self.inputlist=[str(round(eval('1/'+str(listSum)),5))]
 else:
 for k in range(locate+1,len(self.inputlist)):
  del self.inputlist[k]
 self.inputlist.append(str(round(eval('1/'+str(listSum)),5)))
 elif button==self.ButtonList[19]:
 pass
 elif button==self.ButtonList[20]:
 pass
 else:
 self.inputlist.append(button)
 self.count.set(self.inputlist)

关于lambda

百度百科:Lambda表达式是Python中一类特殊的定义函数的形式,使用它可以定义一个匿名函数

与其它语言不同,Python的Lambda表达式的函数体只能有唯一的一条语句,也就是返回值表达式语句

搜索更多文章后理解更多,Lambda函数可以说是对按钮起到“call back”的作用

如果我们不使用Lambda进行中间函数的延迟回调,在创建按钮的同时command绑定的函数会被调用

即如下面两句代码的区别,第二句在进行创建时会直接执行knobDown函数

self.NumButton=tkinter.Button(master=self.tk,relief=GROOVE,bg='#BFEFFF',text=self.ButtonList[20],  font=self.ButtonFont,command=lambda:self.knobDown(self.ButtonList[20]))
self.NumButton=tkinter.Button(master=self.tk,relief=GROOVE,bg='#BFEFFF',text=self.ButtonList[20],  font=self.ButtonFont,command=self.knobDown(self.ButtonList[20]))

更详细的解释可以参考文末最后两个文章,还是前辈写得好

关于单选框

本来想实现PPT中给出的示例-房贷计算的拓展,但是一直这个单选框产生BUG就放弃了

下面的示例是从网上摘抄过来的,具体的网址忘了

就是通过variable绑定一个IntVar() ,通过.get()方式可以获取Radiobutton中value的值

#!/usr/bin/env python
import tkinter
from tkinter import *
import tkinter.font as tkfont
root=tkinter.Tk()
val=tkinter.IntVar()
val.set(0)
def func1():
 if val.get() == 0:
 label.configure(text='radio 0')
 else:
 label.configure(text='radio 1')

label = tkinter.Label(root, text='radio 0')
label.pack()
r0 = tkinter.Radiobutton(text = 'radio0', variable = val, value = 0)
r0.pack()
r1 = tkinter.Radiobutton(text = 'radio1', variable = val, value = 1)
r1.pack()
b = tkinter.Button(root, text='button', command=func1)
b.pack()
root.mainloop()

利用Tkinter(python3.6)实现一个简单计算器

打包

C:\Users\bayi\Desktop\shiyan\progrem
(venv) λ pip install pyinstaller
C:\Users\bayi\Desktop\shiyan\progrem
(venv) λ pyinstaller -F -w -i favicon.ico run.py

一开始因为代码中的设置ico图标为下面代码第一行

windows下打包路径识别有问题,把图标换到一个路径短的地方

修改成绝对路径就OK了(下面代码第二行,exe和ico要放在同一个目录下

self.baoxianTk.icobitmap('favicon.ico')
self.baoxianTk.iconbitmap(os.getcwd()+'/favicon.ico')

效果预览

虽然是现学现卖和对于别人的老知识,但是成功之后还是挺有成就感的(and我似乎对美工要求挑剔........

调颜色和样式能挑半天,包括以前的那个爬虫的前端

利用Tkinter(python3.6)实现一个简单计算器

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
Python中的进程分支fork和exec详解
Apr 11 Python
python 限制函数调用次数的实例讲解
Apr 21 Python
django初始化数据库的实例
May 27 Python
Python socket实现多对多全双工通信的方法
Feb 13 Python
python字符串中匹配数字的正则表达式
Jul 03 Python
Django使用Channels实现WebSocket的方法
Jul 28 Python
对django layer弹窗组件的使用详解
Aug 31 Python
Python 列表的清空方式
Jan 13 Python
Python日志logging模块功能与用法详解
Apr 09 Python
基于python实现检索标记敏感词并输出
May 07 Python
Python图像阈值化处理及算法比对实例解析
Jun 19 Python
一篇文章搞懂python混乱的切换操作与优雅的推导式
Aug 23 Python
python编写朴素贝叶斯用于文本分类
Dec 21 #Python
python并发2之使用asyncio处理并发
Dec 21 #Python
利用Python暴力破解zip文件口令的方法详解
Dec 21 #Python
Python人脸识别初探
Dec 21 #Python
python中判断文件编码的chardet(实例讲解)
Dec 21 #Python
python 设置文件编码格式的实现方法
Dec 21 #Python
Python+OpenCV人脸检测原理及示例详解
Oct 19 #Python
You might like
PHP设计模式之代理模式的深入解析
2013/06/13 PHP
thinkPHP+PHPExcel实现读取文件日期的方法(含时分秒)
2016/07/07 PHP
php版微信公众平台接口开发之智能回复开发教程
2016/09/22 PHP
PHP回调函数简单用法示例
2019/05/08 PHP
php array_map()函数实例用法
2021/03/03 PHP
Alliance vs AM BO3 第一场2.13
2021/03/10 DOTA
jquery图片放大功能简单实现
2013/08/01 Javascript
jquery中focus()函数实现当对象获得焦点后自动把光标移到内容最后
2013/09/29 Javascript
fmt:formatDate的输出格式详解
2014/01/09 Javascript
js正则表达式中test,exec,match方法的区别说明
2014/01/29 Javascript
Jquery 返回json数据在IE浏览器中提示下载的问题
2014/05/18 Javascript
基于JavaScript将表单序列化类型的数据转化成对象的处理(允许对象中包含对象)
2015/12/28 Javascript
【经典源码收藏】基于jQuery的项目常见函数封装集合
2016/06/07 Javascript
vue+egg+jwt实现登录验证的示例代码
2019/05/18 Javascript
Node.js API详解之 module模块用法实例分析
2020/05/13 Javascript
JavaScript字符和ASCII实现互相转换
2020/06/03 Javascript
python开发之thread实现布朗运动的方法
2015/11/11 Python
Python的Tornado框架的异步任务与AsyncHTTPClient
2016/06/27 Python
K-means聚类算法介绍与利用python实现的代码示例
2017/11/13 Python
Python对象属性自动更新操作示例
2018/06/15 Python
pip指定python位置安装软件包的方法
2019/07/12 Python
Python爬取豆瓣视频信息代码实例
2019/11/16 Python
tensorflow-gpu安装的常见问题及解决方案
2020/01/20 Python
python读取yaml文件后修改写入本地实例
2020/04/27 Python
使用python批量修改XML文件中图像的depth值
2020/07/22 Python
python在一个范围内取随机数的简单实例
2020/08/16 Python
NUK奶瓶美国官网:NUK美国
2016/09/26 全球购物
美国孕妇装品牌:Destination Maternity
2018/02/04 全球购物
校园报刊亭创业计划书
2014/01/02 职场文书
教师旷工检讨书
2014/01/18 职场文书
九年级物理教学反思
2014/01/29 职场文书
俞敏洪励志演讲稿
2014/04/29 职场文书
小学生环保标语
2014/06/13 职场文书
五四青年节的活动方案
2014/08/20 职场文书
环境建议书
2015/02/04 职场文书
后勤工作个人总结
2015/02/28 职场文书