@Author: Runsen

本次 Python 小项目主要功能:调用电脑摄像头实现拍照,并使用百度 API 接口实现图像识别。

上次完成了API的封装,这次完成GUI的布局。具体成品如下所示。

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

Tkinter 布局逻辑中最推荐使用的Grid布局。实现机制是将Widget逻辑上分割成表格,在指定的位置放置想要的Widget就可以了。

Grid布局参数说明

参数 作用
column  指定组件插入的列(0 表示第 1 列)
默认值是 0
columnspan  指定用多少列(跨列)显示该组件
row  指定组件插入的行(0 表示第 1 行)
rowspan  指定用多少行(跨行)显示该组件
in_ 将该组件放到该选项指定的组件中
指定的组件必须是该组件的父组件
ipadx   水平方向上的内边距
ipady   垂直方向上的内边距
padx  水平方向上的外边距
pady  垂直方向上的外边距
sticky  控制组件在 grid 分配的空间中的位置
可以使用 "n", "e", "s", "w" 以及它们的组合来定位(ewsn代表东西南北,上北下南左西右东)
使用加号(+)表示拉长填充,例如 "n" + "s" 表示将组件垂直拉长填充网格,"n" + "s" + "w" + "e" 表示填充整个网格
不指定该值则居中显示选项 含义

具体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():# 调用笔记本内置摄像头,所以参数为0,如果有其他的摄像头可以调整参数为1,2cap = cv.VideoCapture(0)img_path = str(int(time.time())) + '.jpg'while True:# 从摄像头读取图片sucess, img = cap.read()# 转为灰度图片# gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)## 显示摄像头cv.imshow('----------please enter "s" to take a picture----------', img)# 保持画面的持续,无限期等待输入k = cv.waitKey(1)if k == 27:# 通过esc键退出摄像cv.destroyAllWindows()breakelif k == ord("s"):# 通过s键保存图片,并退出。cv.imwrite(img_path, img)cv.destroyAllWindows()break# 关闭摄像头cap.release()# 打印日志scr.insert(tk.END, '[{}]拍摄成功...\n'.format(time.strftime('%Y-%m-%d %H:%M:%S')))# 返回图像return img_path# ----------图形界面各个组件功能的设计----------
# 清除窗口日志
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发送图像并获取信息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)))# -------------创建窗口--------------
win = tk.Tk()
win.title('客官先关注微信公众号:Python之王!')
win.geometry('600x300')# ------------窗口组件设计-----------
# grid中的参数: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)  # 设置默认值为第一个,即默认下拉框中的内容numberChosen.grid(row=1, column=1, rowspan=1, sticky=N + E + S + W)
# 下拉框触发动作 (绑定点击事件)
numberChosen.bind('<<ComboboxSelected>>', 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非常不好的方面,而且打包出来的占用内存非常的大

安装:pip install pyinstaller。Pyinstaller具体参数如下所示。

参数 含 义
-F 只生成一个exe文件
–distpath 指定生成的exe存放的目录
–workpath 指定编译中临时文件存放的目录
-i 创建一个目录包含:exe文件、依赖文件
–icon= 指定exe图标
-p 指定exe依赖的包、模块
-d 编译为debug模式,获取运行中的日志信息
-clean 清理编译时临时文件
-c 使用控制台
-w 使用窗口
-version-file 添加exe版本信息

注意点:有的时候在代码最后面加上input(),这样打开exe不会一散而过。由于上面代码本身就是窗口一直显示,无需加上input()。

在打包时候,并没有提示错误,可以顺利打包成 exe 文件。但是在运行打包好的软件时,会提示找不到模块,本人遇到的是找不到第三方模块,例如 cv2 。这时候需要在打包时指定 -p 参数,后面跟上 python 目录下的第三方库模板目录路径 site-packages ,再打包就成功了。

cd 到代码的目录执行 pyinstaller main.py -F -p F:\anaconda\Lib\site-packages

如果Pyinstaller打包报错numpy.core.multiarray failed to import,这是numpy和opencv的不兼容,可以降低numpy的版本

具体代码在微信公众号:Python之王。回复tkinter

本文已收录 GitHub,传送门~ ,里面更有大厂面试完整考点,欢迎 Star。

五十二、GUI布局tkinter完善Python小项目相关推荐

  1. [Python从零到壹] 五十二.图像增强及运算篇之图像掩膜直方图和HS直方图

    欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...

  2. OpenCV学习笔记(五十一)——imge stitching图像拼接stitching OpenCV学习笔记(五十二)——号外:OpenCV 2.4.1 又出来了。。。。。 OpenCV学习笔记(五

    OpenCV学习笔记(五十一)--imge stitching图像拼接stitching stitching是OpenCV2.4.0一个新模块,功能是实现图像拼接,所有的相关函数都被封装在Stitch ...

  3. Python基础笔记_Day14_Python图形化界面、Python GUI、tkinter、Python英汉词典

    Day14_Python图形化界面.Python GUI.tkinter.Python英汉词典 14.01_Python语言基础(Python实现英汉字典)(掌握) 14.02_Python语言基础( ...

  4. 动画骨骼【Visual C++】游戏开发五十二 浅墨DirectX教程二十 骨骼动画来袭(一)...

    间时紧张,先记一笔,后续优化与完善. 本系列文章由zhmxy555(毛星云)编写,载转请注明出处. 文章链接: http://blog.csdn.net/zhmxy555/article/detail ...

  5. JavaWeb学习总结(五十二)——使用JavaMail创建邮件和发送邮件

    JavaWeb学习总结(五十二)--使用JavaMail创建邮件和发送邮件 一.RFC882文档简单说明 RFC882文档规定了如何编写一封简单的邮件(纯文本邮件),一封简单的邮件包含邮件头和邮件体两 ...

  6. 《当程序员的那些狗日日子》(五十二)同学情与差距

    (五十二)同学情与差距 临近春节放假前,我收到了高中一同学志的结婚请柬.想想也快到春节放假了,于是我干脆请了几天假,跟春节假期连在一起,这样就可以提先回家过一个春节长假了. 说起来很巧,志是我到广州后 ...

  7. JavaScript学习(五十二)—继承、call方法和apply方法

    JavaScript学习(五十二)-继承.call方法和apply方法 学习内容 一.继承 二.call方法 三.apply方法 一.继承 所谓继承就是两个构造方法建立起来的某种联系,通过某种联系,可 ...

  8. 硬盘底座linux,微客智品 篇五十二:机械硬盘如何安放?用奥睿科单盘位移动硬盘底座助力新玩法...

    微客智品 篇五十二:机械硬盘如何安放?用奥睿科单盘位移动硬盘底座助力新玩法 2020-01-07 15:36:58 1点赞 10收藏 30评论 随着新一代M.2硬盘的流行与普及,3.5寸机械硬盘愈发变 ...

  9. (五十二):多模态情感分析研究综述_张亚洲

    (五十二):多模态情感分析研究综述_张亚洲 Abstract 1 叙述式多模态情感分析 1. 1 静态多模态情感分析(文本与图像划分为静态文档) 1. 1. 1 基于机器学习的方法 1. 1. 2 基 ...

最新文章

  1. HCTL-2020正交码读写芯片
  2. matlab中PDE工具箱如何使用,使用PDE工具箱求解偏微分方程
  3. asm 32 /64
  4. ubuntu下使用crontab定时器
  5. 关于Juniper ScreenOS MIP/VIP地址说明
  6. Training的第十六天
  7. containsObject 总是不含有,你会用吗
  8. 一招解决4道leetcode hard题,动态规划在字符串匹配问题中的应用
  9. jQuery修改margin
  10. Python的单链表实现
  11. 在Windows mobile 5.0下操作INI文件
  12. 【排错】exchange2013不能显示所有OU
  13. 【ubuntu操作系统】ubuntu系统下第一个C语言程序
  14. 1.爬虫系统学习--爬虫应知知识(后续还会更新)
  15. 计量经济学计算机答案第一章,计量经济学计算机作业
  16. 村田【元宇宙】要火,但不能“起火”—— 电池:半固态凝胶软包电池篇
  17. 如何用SaaS科技赋能中小企业管理
  18. spring入参为指定值,校验java入参的值为规定的值,利用Validator指定值校验注解——一看就会
  19. 北大核刊最新版2020目录_新食品原料目录大全(2020年最新版)
  20. 如果通过这次面试我们单位录用了你,但工作一段时间却发现你根本不适合这个职位,你怎么办?

热门文章

  1. 程序员内功修炼之学好算法和数据结构(一)排序基础、选择排序、插入排序、希尔排序...
  2. Qualcomm(高通)平台开发系列讲解-音频设备操作流程
  3. IEEE-TMI:张孝勇团队开发小鼠精细脑结构自动分割的深度学习算法
  4. 如何正确的进行密码保护?
  5. 推导三次以及四次方程的求根公式
  6. 利用WinRAR快速分发安装小软件,自动解压生成桌面图标
  7. 安卓扁平化之路专题(一)Android 4.4新特性
  8. Linux平台Wiznet w5500移植
  9. [网络安全自学篇] 四十一.中间人攻击和ARP欺骗原理详解及防御机理
  10. 计算机学院心理节活动,心灵相约 拥抱青春 计算机学院心理健康宣传活动