资讯专栏INFORMATION COLUMN

可能是最有颜值的Python Tkinter计算器

princekin / 1046人阅读

摘要:上机实践课程开始了嗯,老师来了之后念了下,然后说开始做吧然后就开始了的之路,以前没接触过的可视化界面虽然这样很不明智但是现在做起来感觉写小工具还挺方便的,当时搜到的第一个库便是就直接开始写了后来发现很不错的样子,下个实验就用吧然后关于计算器

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

然后就开始了Python的GUI之路,以前没接触过PYthon的可视化界面(虽然这样很不明智)
但是现在做起来感觉写小工具还挺方便的,当时搜到的第一个库便是Tkinter就直接开始写了
后来发现QT很不错的样子,下个实验就用QT吧.然后关于Tkinter(python3.6)

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

首先对于python中栈的实现是通过list的方式模拟
pop()出栈,append()入栈
开始一个窗口
做一个可视化的东西,首先想到的坑定是窗口吧
窗口又有很多构成,比如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()

打包
C:UsersayiDesktopshiyanprogrem
(venv) λ pip install pyinstaller

C:UsersayiDesktopshiyanprogrem
(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控件详解
Python数据结构——栈
创建一个只能输入数字的输入框
Tkinter教程之Entry篇
另一个Lambda表达式教程
《Python编程》笔记(七)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/41076.html

相关文章

  • Python的门面担当 - Tkinter

    摘要:在这个窗口之上,可以添加各种输入框按钮文本等,可以增加对各种动作的处理。事件要与特定的控件相绑定,比如按钮有点击事件,输入框有按键事件,窗体有关闭事件等。 在大多数时候,我们都在黑黢黢的控制台里执行 Python 脚本。这看起来很酷很 GEEK。但对于部分场景下的用户来说,这样就不大美观和人性化了:我们需要交互更方便的图形化产品,也就是 GUI (图形用户界面,Graphical Us...

    Lucky_Boy 评论0 收藏0
  • Python小测试 ☀2021最新男女颜值打分小系统标准出炉,看哭无数人...

    导语​​ 哈喽!我是木木子,今天又想我了嘛? 之前不是出过一期Python美颜相机嘛?不知道你们还记得不?这一期的话话题还是围绕上期关于颜值方面来走。 还是原来的配方,还是原来的味道。 偶尔有女生或者说男生都有过这样的经历,偶然照镜子的时候觉得自己美、帅到爆炸。【小编打死不会承认的.jpg】 ​ 但打开无美颜的前置摄像头无滤镜,或者看到真正的漂亮小姐姐,又会感慨自己怎么能这么丑! ​ 颜值打分其...

    wmui 评论0 收藏0
  • Xshell – 高颜值体验好Win系统个人免费SSH客户端软件

    摘要:老蒋在前面的老牌免费开源远程客户端软件文章中有介绍到作为一款老牌免费的远程连接工具我们很多运维工程师也都有使用过。我个人觉得是目前在系统中体验较高颜值较好的免费客户端软件。在安装过程中,我们选择学校个人用户,这个是免费资格的。老蒋在前面的PuTTY – 老牌免费开源Windows SSH远程客户端软件文章中有介绍到Putty作为一款老牌免费的SSH远程连接工具我们很多运维工程师也...

    番茄西红柿 评论0 收藏2637

发表评论

0条评论

princekin

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<