欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

python中的GUI實(shí)現(xiàn)計(jì)算器

 更新時(shí)間:2022年01月24日 17:02:53   作者:柏常青  
這篇文章主要介紹了如何利用python中的GUI實(shí)現(xiàn)計(jì)算器,文章教大家用用python的GUI做界面布局,計(jì)算器代碼熟悉控件的使用方法、優(yōu)化計(jì)算器代碼,解決獲取按鈕文本的方法,具有一定的參考價(jià)值,需要的朋友可以參考一下

一、學(xué)習(xí)目標(biāo):學(xué)會(huì)利用python的GUI做界面布局

  • 手寫計(jì)算器代碼熟悉控件的使用方法
  • 優(yōu)化計(jì)算器代碼,解決 獲取按鈕文本 的方法
  • 了解lambda函數(shù)的傳參優(yōu)點(diǎn)和局限
  • 打包生成自己的計(jì)算器軟件,并獨(dú)立運(yùn)行

二、學(xué)習(xí)內(nèi)容:手寫一個(gè)簡(jiǎn)單計(jì)算器

1、計(jì)算器目標(biāo)圖

目標(biāo)計(jì)算器設(shè)計(jì)分為三個(gè)部分:

背景部分  :

 根:Tk()

展示部分:上方展示算式,下方展示計(jì)算結(jié)果:

按鈕部分:

2、 計(jì)算器計(jì)算功能

  • 加減乘除,放在 = ,按鈕上
  • 回退,放在 <- 按鈕上
  •  清除,放在 MC 按鈕上

3、 代碼實(shí)現(xiàn)與詳細(xì)說明

外觀布局:

首先引入包: from tkinter import *

根據(jù)目標(biāo)圖片設(shè)計(jì)布局按鈕:定義計(jì)算器類,初始化界面控件。

class Calculator:
    def __init__(self, master):
        self.master = master
        self.master.title("Calculator")
        self.master.resizable(0, 0)  # 設(shè)置窗口不可拉伸
        self.master.geometry('320x420')  # 設(shè)置主窗口的初始尺寸

        self.result = StringVar()  # 用于顯示結(jié)果的可變文本
        self.equation = StringVar()  # 顯示計(jì)算方程
        self.result.set(' ')
        self.equation.set('0')
        # 顯示框
        self.show_result_eq = Label(self.master, bg='white', fg='black',
                                    font=('Arail', '16'), bd='0',
                                    textvariable=self.equation, anchor='se')
        self.show_result = Label(self.master, bg='white', fg='black',
                                 font=('Arail', '20'), bd='0',
                                 textvariable=self.result, anchor='se')
        # 按鈕
        self.button_back = Button(self.master, text='<-', bg='DarkGray', command=self.back)  # 返回
        self.button_lbracket = Button(self.master, text='(', bg='DarkGray', command=lambda: self.getNum('('))  # 左括號(hào)
        self.button_rbracket = Button(self.master, text=')', bg='DarkGray', command=lambda: self.getNum(')'))  # 左括號(hào)
        self.button_division = Button(self.master, text='÷', bg='DarkGray', command=lambda: self.getNum('÷'))  # 除號(hào)
        # 7 8 9 4 5 6 1 2 3
        self.button_7 = Button(self.master, text='7', bg='DarkGray', command=lambda: self.getNum('7'))  # 7號(hào)
        self.button_8 = Button(self.master, text='8', bg='DarkGray', command=lambda: self.getNum('8'))  # 8號(hào)
        self.button_9 = Button(self.master, text='9', bg='DarkGray', command=lambda: self.getNum('9'))  # 9號(hào)
        self.button_multiplication = Button(self.master, text='*', bg='DarkGray',
                                            command=lambda: self.getNum('*'))  # 乘號(hào)
        # 按鈕的command參數(shù),是回調(diào)函數(shù)。lambda函數(shù)是為了可以傳參數(shù)給回調(diào)函數(shù)
        self.button_4 = Button(self.master, text='4', bg='DarkGray', command=lambda: self.getNum('4'))  # 4號(hào)
        self.button_5 = Button(self.master, text='5', bg='DarkGray', command=lambda: self.getNum('5'))  # 5號(hào)
        self.button_6 = Button(self.master, text='6', bg='DarkGray', command=lambda: self.getNum('6'))  # 6號(hào)
        self.button_minus = Button(self.master, text='-', bg='DarkGray', command=lambda: self.getNum('-'))  # -號(hào)

        self.button_1 = Button(self.master, text='1', bg='DarkGray', command=lambda: self.getNum('1'))  # 1號(hào)
        self.button_2 = Button(self.master, text='2', bg='DarkGray', command=lambda: self.getNum('2'))  # 2號(hào)
        self.button_3 = Button(self.master, text='3', bg='DarkGray', command=lambda: self.getNum('3'))  # 3號(hào)
        self.button_plus = Button(self.master, text='+', bg='DarkGray', command=lambda: self.getNum('+'))  # +號(hào)
        # 控制按鈕 0 .
        self.button_MC = Button(self.master, text='MC', bg='DarkGray', command=self.clear)  # MC
        self.button_0 = Button(self.master, text='0', bg='DarkGray', command=lambda: self.getNum('0'))  # 0
        self.button_dot = Button(self.master, text='.', bg='DarkGray', command=lambda: self.getNum('.'))  # .
        self.button_eq = Button(self.master, text='=', bg='DarkGray', command=self.run)  # =

        # Layout布局
        self.show_result_eq.place(x='10', y='10', width='300', height='50')
        self.show_result.place(x='10', y='60', width='300', height='50')

        self.button_back.place(x='10', y='150', width='60', height='40')
        self.button_lbracket.place(x='90', y='150', width='60', height='40')
        self.button_rbracket.place(x='170', y='150', width='60', height='40')
        self.button_division.place(x='250', y='150', width='60', height='40')
        self.button_7.place(x='10', y='205', width='60', height='40')
        self.button_8.place(x='90', y='205', width='60', height='40')
        self.button_9.place(x='170', y='205', width='60', height='40')
        self.button_multiplication.place(x='250', y='205', width='60', height='40')

        self.button_4.place(x='10', y='260', width='60', height='40')
        self.button_5.place(x='90', y='260', width='60', height='40')
        self.button_6.place(x='170', y='260', width='60', height='40')
        self.button_minus.place(x='250', y='260', width='60', height='40')

        self.button_1.place(x='10', y='315', width='60', height='40')
        self.button_2.place(x='90', y='315', width='60', height='40')
        self.button_3.place(x='170', y='315', width='60', height='40')
        self.button_plus.place(x='250', y='315', width='60', height='40')

        self.button_MC.place(x='10', y='370', width='60', height='40')
        self.button_0.place(x='90', y='370', width='60', height='40')
        self.button_dot.place(x='170', y='370', width='60', height='40')
        self.button_eq.place(x='250', y='370', width='60', height='40')

重點(diǎn)說明:

按鈕的command參數(shù),是回調(diào)函數(shù)。lambda函數(shù)是為了可以傳參數(shù)給回調(diào)函數(shù)。

lambda匿名函數(shù)的使用: command=lambda: self.getNum('3'))

注意這里傳的參數(shù)是字符串: '3' 。每一個(gè)按鈕點(diǎn)擊想要獲取的文本值不同,所以對(duì)應(yīng)的參數(shù)各不相同。

從而,也導(dǎo)致初始化界面代碼看起來(lái)太冗長(zhǎng)了。

功能布局:

設(shè)置回退 back ,符號(hào)獲取 getNum ,清除 clear ,計(jì)算 run 方法。

def back(self):
        temp_equ = self.equation.get()
        self.equation.set(temp_equ[:-1])  # 一個(gè)一個(gè)刪

    def getNum(self, arg):
        temp_equ = self.equation.get()  # 輸入算式
        temp_result = self.result.get()

        # 判斷基本語(yǔ)法錯(cuò)誤
        if temp_result != ' ':  # 計(jì)算器輸入前還沒有結(jié)果,那么結(jié)果區(qū)域應(yīng)該設(shè)置為空。
            self.result.set(' ')
        if temp_equ == '0' and (arg not in ['.', '+', '-', '*', '÷']):  # 如果首次輸入為0,則緊跟則不能是數(shù)字,只是小數(shù)點(diǎn)或運(yùn)算符
            temp_equ = ''
        if len(temp_equ) > 2 and temp_equ[-1] == '0':  # 運(yùn)算符后面也不能出現(xiàn)0+數(shù)字的情形03,09,x
            if (temp_equ[-2] in ['+', '-', '*', '÷']) and (
                    arg in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '(']):
                temp_equ = temp_equ[:-1]
        temp_equ = temp_equ + arg
        self.equation.set(temp_equ)

    def clear(self):
        self.equation.set('0')
        self.result.set(' ')

    def run(self):
        temp_equ = self.equation.get()
        temp_equ = temp_equ.replace('÷', '/')
        if temp_equ[0] in ['+', '-', '*', '÷']:
            temp_equ = '0' + temp_equ
            print(temp_equ)
        try:
            answer = '%.4f' % eval(temp_equ)  # 保留兩位小數(shù)
            self.result.set(str(answer))
        except (ZeroDivisionError, SyntaxError):  # 其他除0錯(cuò)誤,或語(yǔ)法錯(cuò)誤返回Error
            self.result.set(str('Error'))

測(cè)試實(shí)驗(yàn)與總結(jié):

 測(cè)試:

if __name__ == "__main__":
    root = Tk()
    my_cal = Calculator(root)
    root.mainloop()

小結(jié)

  • 1. 按鈕的command參數(shù)設(shè)置的是回調(diào)函數(shù),點(diǎn)擊按鈕后的操作由函數(shù)完成。
  • 2.將回調(diào)函數(shù)設(shè)置成匿名函數(shù), lambda函數(shù)是可以傳參數(shù)給回調(diào)函數(shù)。這個(gè)參數(shù)是在調(diào)用函數(shù)的時(shí)候才傳入,不會(huì)在定義的時(shí)候保存。
  • 3. 關(guān)于控件的類型,控件的屬性,控件的放置方式

控件類型,可以通過多dir函數(shù)查看:比如 dir(tkinter) ,找到控件

控件:19
'Button','Canvas'畫布,'Text'文本,'Checkbutton'復(fù)選按鈕,'Radiobutton'單選按鈕,'Frame'框架,'Message'消息,
'Entry'條目實(shí)體,'Label'標(biāo)簽,'LabelFrame'標(biāo)簽框架, 'Listbox'列表框,'Menu'菜單, 'Menubutton'菜單按鈕,
'Scale'縮放,'Scrollbar'滾動(dòng)條,'Toplevel'頂級(jí),'Spinbox'旋轉(zhuǎn)框,'PanedWindow'窗格窗口,'tkMessageBox'消息框

控件屬性查看: dir(Button) 把用得到的控件都查一遍,就清楚怎么用它們了。

放置方式–集合布局:當(dāng)定義一個(gè)控件,均需要讓它布局到窗口上,用到三個(gè)函數(shù): pack , grid , place
pack 的參數(shù)side,可設(shè)置 上下左右布局 ;

grid 的參數(shù)row,column,可設(shè)置 行列網(wǎng)格布局 ;

同一塊畫布不能混合使用。

關(guān)于如何避免同志們亂寫算式,使軟件奔潰的問題。

本計(jì)算器計(jì)算功能是通過獲取將輸入表達(dá)式,利用eval()函數(shù)來(lái)執(zhí)行python代碼字符串的。

那么就要杜絕不合理的輸入表達(dá)式,不能阻止人家亂點(diǎn),可以在程序中設(shè)置 try...except...else...finally 語(yǔ)句捕捉異常,設(shè)置合理的的響應(yīng)。

三、學(xué)習(xí)優(yōu)化:學(xué)會(huì)優(yōu)化冗于代碼

優(yōu)化方向:

  • 1、 初始化布局頁(yè)面代碼冗余;
  • 2、 lambda匿名函數(shù)包裹回調(diào)函數(shù)時(shí)傳參的問題

代碼實(shí)現(xiàn):這里主要優(yōu)化初始化函數(shù),其他函數(shù)采用繼承。

優(yōu)化計(jì)算器類Calc繼承Calculatorback,clear,run,getNum。增加initPage來(lái)定義頁(yè)面控件布局。

# 計(jì)算器,優(yōu)化程序
class Calc(Calculator):
    def __init__(self, master):
        self.master = master
        self.master.title("Calculator")
        self.master.resizable(0, 0)  # 設(shè)置窗口不可拉伸
        self.master.geometry('320x420')  # 設(shè)置主窗口的初始尺寸

        self.result = StringVar()  # 用于顯示結(jié)果的可變文本
        self.equation = StringVar()  # 顯示計(jì)算方程
        self.result.set(' ')
        self.equation.set('0')

        self.labels = ['<-', '(', ')', '÷',
                       '7', '8', '9', '*',
                       '4', '5', '6', '-',
                       '1', '2', '3', '+',
                       'MC', '0', '.', '=',
                       ]
        # 顯示框
        self.show_result_eq = Label(self.master, bg='white', fg='black',
                                    font=('Arail', '16'), bd='0',
                                    textvariable=self.equation, anchor='se')
        self.show_result = Label(self.master, bg='white', fg='black',
                                 font=('Arail', '20'), bd='0',
                                 textvariable=self.result, anchor='se')
        # 按鈕
        # self.button_dict = {}
        # Layout布局
        self.show_result_eq.place(x='10', y='10', width='300', height='50')
        self.show_result.place(x='10', y='60', width='300', height='50')

        self.initPage()

    def initPage(self):
        X = ['10', '90', '170', '250']
        Y = ['150', '205', '260', '315', '370']
        lengths = len(self.labels)  # 20
        y_ = -1
        # 設(shè)置按鈕并布局
        for label in self.labels:
            print(label)
            index = self.labels.index(label)
            x_ = index % 4
            if x_ == 0:
                y_ += 1

            if label == '<-':
                button = Button(self.master, text=label, bg='DarkGray', command=self.back)
                button.place(x=X[x_], y=Y[y_], width='60', height='40')
            elif label == '=':
                button = Button(self.master, text=label, bg='DarkGray', command=self.run)
                button.place(x=X[x_], y=Y[y_], width='60', height='40')
            elif label == 'MC':
                button = Button(self.master, text=label, bg='DarkGray', command=self.clear)
                button.place(x=X[x_], y=Y[y_], width='60', height='40')
            else:
                # 因?yàn)閘ambda函數(shù)有傳參功能,但只有調(diào)用的時(shí)候才傳參,所以數(shù)字按鈕永遠(yuǎn)會(huì)調(diào)用最后一個(gè)label值。解決方案是自己洗一個(gè)button來(lái)保存label值
                button = NumButton(self.master, text=label, bg='DarkGray', fun=self.getNum)
                button.btn.place(x=X[x_], y=Y[y_], width='60', height='40')
            # self.button_dict[label] = button

重點(diǎn):以上代碼,倒數(shù)第二行,我采用自定義的NumButton,而不是原有的Butoon。

因?yàn)榧词鼓涿瘮?shù)lambda函數(shù)有傳參功能,但只有調(diào)用的時(shí)候才傳參,所以for循環(huán)到最后,label變量的值永遠(yuǎn)為列表最后一個(gè) = 等于符號(hào),一度讓人無(wú)解,只能自定義一個(gè)按鈕類型 NumButton ,來(lái)保存中間值。使按鈕們都有自己的文本值,并且command回調(diào)的時(shí)候能夠準(zhǔn)確傳參。

class NumButton():
    def __init__(self, frame, text, fun, **kwargs):
        # side = kwargs.get('side') if 'side' in kwargs else ()  # 此處沒用上
        self.btn = Button(
            frame,
            text=text,
            activeforeground="blue",
            activebackground="pink",
            bg='DarkGray',
            command=lambda: fun(text)
        )


注意:

  • 形式參數(shù) frame, text, fun
  • frame是根部件。
  • text按鈕的標(biāo)簽文本,
  • fun函數(shù)對(duì)象,就是待回調(diào)的函數(shù)。

測(cè)試總結(jié):

if __name__ == "__main__":
    root = Tk()
    # my_cal = Calculator(root)
    my_cal = Calc(root)
    root.mainloop()


自定義的NumButton設(shè)置了按鈕激活時(shí)背景和字體的顏色變化,所以有點(diǎn)顏色。Button自己也可以設(shè)置的。

測(cè)試沒有問題,就要開始打包:

1.確定安裝pyinstaller包,沒有可以在環(huán)境下安裝: conda install pyinstaller pip install pyinstaller
2. 打包: pyinstaller -F calc.py -w
3. 打包生成可執(zhí)行exe文件不了解請(qǐng)參考博文。

到此這篇關(guān)于python中的GUI實(shí)現(xiàn)計(jì)算器的文章就介紹到這了,更多相關(guān)python的GUI計(jì)算器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python利用Beautiful Soup模塊修改內(nèi)容方法示例

    Python利用Beautiful Soup模塊修改內(nèi)容方法示例

    Beautiful Soup是一個(gè)可以從HTML或XML文件中提取數(shù)據(jù)的Python 庫(kù)。它能夠通過你喜歡的轉(zhuǎn)換器實(shí)現(xiàn)慣用的文檔導(dǎo)航、查找、修改文檔的方式。他還能夠修改HTML/XML文檔的內(nèi)容。這篇文章主要介紹了Python利用Beautiful Soup模塊修改內(nèi)容的方法,需要的朋友可以參考下。
    2017-03-03
  • 在python下使用tensorflow判斷是否存在文件夾的實(shí)例

    在python下使用tensorflow判斷是否存在文件夾的實(shí)例

    今天小編就為大家分享一篇在python下使用tensorflow判斷是否存在文件夾的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧
    2019-06-06
  • 基于PyQt4和PySide實(shí)現(xiàn)輸入對(duì)話框效果

    基于PyQt4和PySide實(shí)現(xiàn)輸入對(duì)話框效果

    這篇文章主要為大家詳細(xì)介紹了基于PyQt4和PySide實(shí)現(xiàn)輸入對(duì)話框效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-02-02
  • python交互式圖形編程實(shí)例(三)

    python交互式圖形編程實(shí)例(三)

    這篇文章主要為大家詳細(xì)介紹了python交互式圖形編程實(shí)例第三篇,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • python Canny邊緣檢測(cè)算法的實(shí)現(xiàn)

    python Canny邊緣檢測(cè)算法的實(shí)現(xiàn)

    這篇文章主要介紹了python Canny邊緣檢測(cè)算法的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • Pandas.DataFrame時(shí)間序列數(shù)據(jù)處理的實(shí)現(xiàn)

    Pandas.DataFrame時(shí)間序列數(shù)據(jù)處理的實(shí)現(xiàn)

    本文主要介紹了Pandas.DataFrame時(shí)間序列數(shù)據(jù)處理的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • Python第三方庫(kù)h5py_讀取mat文件并顯示值的方法

    Python第三方庫(kù)h5py_讀取mat文件并顯示值的方法

    今天小編就為大家分享一篇Python第三方庫(kù)h5py_讀取mat文件并顯示值的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧
    2019-02-02
  • 一起來(lái)學(xué)習(xí)一下python的數(shù)字類型

    一起來(lái)學(xué)習(xí)一下python的數(shù)字類型

    這篇文章主要為大家詳細(xì)介紹了python的數(shù)字類型,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-01-01
  • python利用蒙版摳圖(使用PIL.Image和cv2)輸出透明背景圖

    python利用蒙版摳圖(使用PIL.Image和cv2)輸出透明背景圖

    這篇文章主要介紹了python利用蒙版摳圖(使用PIL.Image和cv2)輸出透明背景圖,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • python判斷列表字典字符串元組是否存在某個(gè)值或者空值(多種方法)

    python判斷列表字典字符串元組是否存在某個(gè)值或者空值(多種方法)

    這篇文章主要介紹了python判斷列表字典字符串元組是否存在某個(gè)值或者空值,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2024-02-02

最新評(píng)論