多是最有顏值的Python Tkinter計算器

上機實踐課程開始了,嗯,老師來了以後唸了下PPT,而後說:開始作吧.........html

而後就開始了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()的做用
若是咱們刪除它,窗口會一閃而過,它就是爲了防止這種狀況python

面板顯示

作成計算器以後坑定要先是計算結果,這裏就須要生成顯示面板
固然咱們也會很天然地聯想到顯示內容的字體設置等需求,具體事例在下面代碼git

....
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()的方式方便的改變面板的內容github

按鈕,輸入框設置

按鈕,輸入框的參數和麪板裏面的是類似的編程

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

其中刪除輸入框的輸入內容windows

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內容
若是是這三種符號則作出對應的處理app

其中須要注意若是是多位數或者帶有符號式子
不能直接進行變換,須要判斷你要轉置的數字的位數,個人具體方式以下
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:\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控件詳解
Python數據結構——棧
建立一個只能輸入數字的輸入框
Tkinter教程之Entry篇
另外一個Lambda表達式教程
《Python編程》筆記(七)

相關文章
相關標籤/搜索