1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        五十二、GUI布局tkinter完善Python小項目

        共 5643字,需瀏覽 12分鐘

         ·

        2020-12-05 17:50


        「@Author:Runsen」

        本次 Python 小項目主要功能:調(diào)用電腦攝像頭實現(xiàn)拍照,并使用百度 API 接口實現(xiàn)圖像識別。

        上次完成了API的封裝,這次完成GUI的布局。具體成品如下所示。

        拍照保存圖片采用的是opencv中的imwrite方法,具體的示例查看上上篇文章。

        Tkinter 布局邏輯中最推薦使用的Grid布局。實現(xiàn)機制是將Widget邏輯上分割成表格,在指定的位置放置想要的Widget就可以了。

        Grid布局參數(shù)說明

        參數(shù)作用
        column?指定組件插入的列(0 表示第 1 列)
        默認(rèn)值是 0
        columnspan?指定用多少列(跨列)顯示該組件
        row?指定組件插入的行(0 表示第 1 行)
        rowspan?指定用多少行(跨行)顯示該組件
        in_將該組件放到該選項指定的組件中
        指定的組件必須是該組件的父組件
        ipadx??水平方向上的內(nèi)邊距
        ipady??垂直方向上的內(nèi)邊距
        padx?水平方向上的外邊距
        pady?垂直方向上的外邊距
        sticky?控制組件在 grid 分配的空間中的位置
        可以使用 "n", "e", "s", "w" 以及它們的組合來定位(ewsn代表東西南北,上北下南左西右東)
        使用加號(+)表示拉長填充,例如 "n" + "s" 表示將組件垂直拉長填充網(wǎng)格,"n" + "s" + "w" + "e" 表示填充整個網(wǎng)格
        不指定該值則居中顯示選項 含義

        具體main.py代碼如下。

        """
        @Author:Runsen
        @WeChat:RunsenLiu
        @微信公眾號:Python之王
        @CSDN:https://blog.csdn.net/weixin_44510615
        @Github:https://github.com/MaoliRUNsen
        @Date:2020/11/29
        """

        import?time
        import?cv2?as?cv??#?pip?install?opencv-python
        import?tkinter?as?tk
        from?tkinter?import?ttk??#?下拉框依賴庫
        from?tkinter?import?scrolledtext??#?滾動文本框依賴庫
        from?tkinter?import?N,E,S,W
        #?引入Baidu_API類?(上次文章)
        from?baidu_api?import?Baidu_API

        #?拍照
        def?take_a_photo():
        ????#?調(diào)用筆記本內(nèi)置攝像頭,所以參數(shù)為0,如果有其他的攝像頭可以調(diào)整參數(shù)為1,2
        ????cap?=?cv.VideoCapture(0)
        ????img_path?=?str(int(time.time()))?+?'.jpg'
        ????while?True:
        ????????#?從攝像頭讀取圖片
        ????????sucess,?img?=?cap.read()
        ????????#?轉(zhuǎn)為灰度圖片
        ????????#?gray?=?cv.cvtColor(img,?cv.COLOR_BGR2GRAY)#
        ????????#?顯示攝像頭
        ????????cv.imshow('----------please?enter?"s"?to?take?a?picture----------',?img)
        ????????#?保持畫面的持續(xù),無限期等待輸入
        ????????k?=?cv.waitKey(1)
        ????????if?k?==?27:
        ????????????#?通過esc鍵退出攝像
        ????????????cv.destroyAllWindows()
        ????????????break
        ????????elif?k?==?ord("s"):
        ????????????#?通過s鍵保存圖片,并退出。
        ????????????cv.imwrite(img_path,?img)
        ????????????cv.destroyAllWindows()
        ????????????break
        ????#?關(guān)閉攝像頭
        ????cap.release()
        ????#?打印日志
        ????scr.insert(tk.END,?'[{}]拍攝成功...\n'.format(time.strftime('%Y-%m-%d?%H:%M:%S')))
        ????#?返回圖像
        ????return?img_path

        #?----------圖形界面各個組件功能的設(shè)計----------
        #?清除窗口日志
        def?clear_the_window():
        ????scr.delete(1.0,?tk.END)

        #?退出軟件
        def?exit():
        ????win.quit()

        #?下拉框選項選擇
        def?select_ttk(event):
        ????global?numberChosen
        ????#?顏值評分
        ????if?numberChosen.current()?==?1:
        ????????#?獲取圖像
        ????????img_path?=?take_a_photo()

        ????????try:
        ????????????#?向API發(fā)送圖像并獲取信息
        ????????????score,?age,?gender,?race?=?Baidu_API().face_detect(img_path=img_path)

        ????????????#?打印日志
        ????????????scr.insert(tk.END,?'[{}]年齡「{}」性別「{}」人種「{}」\n'.format(time.strftime('%Y-%m-%d?%H:%M:%S'),?age,?gender,?race))
        ????????????scr.insert(tk.END,?'[{}]顏值評分為:{}/100?分\n'.format(time.strftime('%Y-%m-%d?%H:%M:%S'),?score))
        ????????except:
        ????????????scr.insert(tk.END,?'[{}]{}'.format(time.strftime(time.strftime('%Y-%m-%d?%H:%M:%S')),
        ???????????????????????????????????????????????Baidu_API().face_detect(img_path=img_path)))
        ????#?手勢識別
        ????if?numberChosen.current()?==?2:
        ????????scr.insert(tk.END,?'[{}]請將您的手勢放置攝像頭前...\n'.format(time.strftime('%Y-%m-%d?%H:%M:%S')))
        ????????time.sleep(0.1)
        ????????img_path?=?take_a_photo()
        ????????try:
        ????????????classname_en,?classname_zh?=?Baidu_API().gesture(img_path=img_path)
        ????????????scr.insert(tk.END,
        ???????????????????????'[{}]手勢大意:{}({})\n'.format(time.strftime('%Y-%m-%d?%H:%M:%S'),?classname_zh,?classname_en))
        ????????except:
        ????????????scr.insert(tk.END,
        ???????????????????????'[{}]{}\n'.format(time.strftime('%Y-%m-%d?%H:%M:%S'),?Baidu_API().gesture(img_path=img_path)))
        ????#?智能人臉摳圖
        ????if?numberChosen.current()?==?3:
        ????????scr.insert(tk.END,?'智能人臉摳圖\n'.format(time.strftime('%Y-%m-%d?%H:%M:%S')))
        ????????img_path?=?take_a_photo()
        ????????out_path?=?str(int(time.time()))?+?'.jpg'
        ????????try:
        ????????????Baidu_API().body_seg(img_path=img_path,?out_path=out_path)
        ????????????scr.insert(tk.END,?'完成智能人臉摳圖')
        ????????except:
        ????????????scr.insert(tk.END,?'[{}]{}\n'.format(time.strftime('%Y-%m-%d?%H:%M:%S'),
        ?????????????????????????????????????????????????Baidu_API().body_seg(img_path=img_path,?out_path=None)))


        #?-------------創(chuàng)建窗口--------------
        win?=?tk.Tk()
        win.title('客官先關(guān)注微信公眾號:Python之王!')
        win.geometry('600x300')

        #?------------窗口組件設(shè)計-----------
        # grid中的參數(shù):column, columnspan, in, ipadx, ipady, padx, pady, row, rowspan,sticky

        #?下拉框組件
        number?=?tk.StringVar
        numberChosen?=?ttk.Combobox(win,?textvariable=number)
        numberChosen['value']?=?('please?select',?'給我的顏值打個分吧!',?'識別一下我的手勢',?'智能人臉摳圖')

        numberChosen.current(0)??#?設(shè)置默認(rèn)值為第一個,即默認(rèn)下拉框中的內(nèi)容

        numberChosen.grid(row=1,?column=1,?rowspan=1,?sticky=N?+?E?+?S?+?W)
        #?下拉框觸發(fā)動作?(綁定點擊事件)
        numberChosen.bind('<>',?select_ttk)

        #?清除按鈕組件
        tk.Button(win,?cnf={'text':?'clear',?'command':?clear_the_window}).grid(row=1,?column=2,?ipadx=1,?sticky=N?+?E?+?S?+?W)

        #?退出按鈕組件
        tk.Button(win,?cnf={'text':?'exit',?'command':?exit}).grid(row=1,?column=3,?ipadx=1,?sticky=N?+?E?+?S?+?W)

        #?滾動文本框組件
        scr?=?scrolledtext.ScrolledText(win)
        scr.grid(row=2,?column=1,?columnspan=3,?rowspan=1)

        #?使窗口一直顯示
        win.mainloop()

        最后使用Pyinstaller打包即可。

        Java 一次編譯到處運行,Python沒有這么好本事,Python有一個pyinstaller可以打包exe,在window平臺下運行,這也是Python非常不好的方面,而且打包出來的占用內(nèi)存非常的大

        安裝:pip install pyinstaller。Pyinstaller具體參數(shù)如下所示。

        參數(shù)含 義
        -F只生成一個exe文件
        –distpath指定生成的exe存放的目錄
        –workpath指定編譯中臨時文件存放的目錄
        -i創(chuàng)建一個目錄包含:exe文件、依賴文件
        –icon=指定exe圖標(biāo)
        -p指定exe依賴的包、模塊
        -d編譯為debug模式,獲取運行中的日志信息
        -clean清理編譯時臨時文件
        -c使用控制臺
        -w使用窗口
        -version-file添加exe版本信息

        注意點:有的時候在代碼最后面加上input(),這樣打開exe不會一散而過。由于上面代碼本身就是窗口一直顯示,無需加上input()。

        在打包時候,并沒有提示錯誤,可以順利打包成 exe 文件。但是在運行打包好的軟件時,會提示找不到模塊,本人遇到的是找不到第三方模塊,例如 cv2 ?。這時候需要在打包時指定 -p 參數(shù),后面跟上 python 目錄下的第三方庫模板目錄路徑 site-packages ,再打包就成功了。

        cd 到代碼的目錄執(zhí)行 pyinstaller main.py -F -p F:\anaconda\Lib\site-packages

        如果Pyinstaller打包報錯numpy.core.multiarray failed to import,這是numpy和opencv的不兼容,可以降低numpy的版本。

        具體代碼在微信公眾號:Python之王?;貜?fù):tkinter

        ?

        本文已收錄 GitHub,傳送門~[1] ,里面更有大廠面試完整考點,歡迎 Star。

        ?


        Reference

        [1]

        傳送門~: https://github.com/MaoliRUNsen/runsenlearnpy100


        更多的文章

        點擊下面小程序


        - END -


        瀏覽 56
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            四虎永久免费地址 | 日韩欧美三级片www麻豆 | 欧美黄色一级生活片 | 三级在线播放视频 | 亚洲高清无码免费观看 | 18禁成人福利网站视频播放 | 欧美性爱XXXX黑人XYX性爽 | 91电影 | 99人妻久久 | 少妇做受 视频网站免费 |