利用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中input与raw_input 之间的比较
Aug 20 Python
Python基于dom操作xml数据的方法示例
May 12 Python
python利用itertools生成密码字典并多线程撞库破解rar密码
Aug 12 Python
softmax及python实现过程解析
Sep 30 Python
Python turtle库绘制菱形的3种方式小结
Nov 23 Python
python groupby 函数 as_index详解
Dec 16 Python
python 浅谈serial与stm32通信的编码问题
Dec 18 Python
Python 多线程共享变量的实现示例
Apr 17 Python
Python selenium环境搭建实现过程解析
Sep 08 Python
详解Selenium-webdriver绕开反爬虫机制的4种方法
Oct 28 Python
如何在 Matplotlib 中更改绘图背景的实现
Nov 26 Python
python爬虫利器之requests库的用法(超全面的爬取网页案例)
Dec 17 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/07/05 PHP
PHP+ajax分页实例简析
2015/12/07 PHP
解决 firefox 不支持 document.all的方法
2007/03/12 Javascript
一些mootools的学习资源
2010/02/07 Javascript
offsetHeight在OnLoad中获取为0的现象
2013/07/22 Javascript
js函数返回多个返回值的示例代码
2013/11/05 Javascript
Javascript实现简单的富文本编辑器附演示
2014/06/16 Javascript
浅谈JavaScript Math和Number对象
2015/01/26 Javascript
js运动动画的八个知识点
2015/03/12 Javascript
JavaScript实现向setTimeout执行代码传递参数的方法
2015/04/16 Javascript
javascript中DOM复选框选择用法实例
2015/05/14 Javascript
jQuery实现自定义右键菜单的树状菜单效果
2015/09/02 Javascript
微信小程序 form组件详解
2016/10/25 Javascript
JavaScript数据结构之二叉树的查找算法示例
2017/04/13 Javascript
vue vue-Router默认hash模式修改为history需要做的修改详解
2018/09/13 Javascript
JavaScript函数定义方法实例详解
2019/03/05 Javascript
javascript实现贪吃蛇小练习
2020/07/05 Javascript
微信小程序中target和currentTarget的区别小结
2020/11/06 Javascript
python网络编程实例简析
2014/09/26 Python
解决Python获取字典dict中不存在的值时出错问题
2018/10/17 Python
python频繁写入文件时提速的方法
2019/06/26 Python
Python项目 基于Scapy实现SYN泛洪攻击的方法
2019/07/23 Python
Wolford法国官网:奥地利奢侈内衣品牌
2020/08/11 全球购物
DBA的职责都有哪些
2012/05/16 面试题
汉语专业应届生求职信
2013/10/01 职场文书
中职应届生会计求职信
2013/10/23 职场文书
小区门卫管理制度
2014/01/29 职场文书
经典商业广告词
2014/03/13 职场文书
工厂门卫的岗位职责
2014/07/27 职场文书
2014年学生会工作总结范文
2014/11/07 职场文书
毕业生见习报告总结
2014/11/08 职场文书
2014年安置帮教工作总结
2014/12/11 职场文书
2014城乡环境综合治理工作总结
2014/12/19 职场文书
校长新学期致辞
2015/07/30 职场文书
奖学金发言稿(范文)
2019/08/21 职场文书
Python基础之数据结构详解
2021/04/28 Python