介绍
项目名称:药片缺陷检测Demo
本项目是一个基于Python标准GUI库Tkinter,开发的支持跨平台的GUI程序——药片缺陷检测桌面应用程序。可通过打包工具打包成一个桌面应用;其主要是检测药片
基于Python标准GUI库Tkinter; 2.GUI控件布局 3.缺陷检测函数
安装教程
(推荐使用Pycharm开发工具)
下载文件并打开项目,配置项目使用的解释器,导入相应的库函数;
from tkinter import *
from PIL import Image, ImageTk # 导入图像处理函数库
from tkinter import filedialog # 导入文件对话框函数库
import tkinter as tk
import os,sys,subprocess
import time
修改相应的路径,推荐使用绝对路径。(注意:一定要根据自己的存放位置进行修改配置,尤其是本地控件的图片,否则打不开会报错)
程序说明:
一个最简单的 Tkinter 程序至少应包含以下四个部分:
导入 tkinter 模块
创建主窗口,也称 root 窗口(即根窗口)
添加人机交互控件,同时编写相应的事件函数
通过主循环(mainloop)来显示主窗口
控件类型 | 控件名称 | 控件类型 | 控件名称 | 控件类型 | 控件名称 | 控件类型 | 控件名称 |
Button | 按钮 | Entry | 文本框输入框 | Menubutton | 菜单按钮控件 | Lable | 标签控件 |
Canvas | 画布 | Frame | 框架(容器)控件 | Message | 信息控件 | Text | 多行文本框 |
GUI图形部分
# 主窗口
win = Tk()
win.title('药品缺陷检测')
win.geometry('600x500+420+200')
# 主窗口
win = Tk()
win.title('药品缺陷检测')
win.geometry('600x500+420+200')
# 创建主菜单栏
menubar = Menu(win)
# 创建子菜单
menuFile = Menu(menubar)
menuEdit = Menu(menubar)
menuHelp = Menu(menubar)
# 将子菜单加入到主菜单栏
menubar.add_cascade(label="文件", menu=menuFile)
menubar.add_cascade(label="编辑", menu=menuEdit)
menubar.add_cascade(label="帮助", menu=menuHelp)
# 添加菜单项
menuFile.add_command(label="打开 ")
menuFile.add_command(label="保存")
menuFile.add_separator()
menuFile.add_command(label="退出")
menuEdit.add_command(label="剪切 ")
menuEdit.add_command(label="复制")
menuEdit.add_command(label="粘贴")
menuEdit.add_command(label="删除")
menuEdit.add_separator()
menuEdit.add_command(label="查找 ")
menuEdit.add_command(label="全选")
menuHelp.add_command(label="联系支持 ")
menuHelp.add_command(label="提交问题")
# 将主菜单栏加到根窗口
win["menu"] = menubar
# Label图形控件
image_path0 = tk.PhotoImage(file = './data/icon1.png')
label_Img0 = tk.Label(win, width=64, height=14,image=image_path0,)
label_Img0.place(x=10, y=10,width=64, height=44)
image_path1 = tk.PhotoImage(file ='./data/icon2.png')
label_Img1 = tk.Label(win, width=64, height=14,image=image_path1)
label_Img1.place(x=80, y=10,width=64, height=44)
image_path2 = tk.PhotoImage(file = './data/icon3.png')
label_Img2 = tk.Label(win, width=64, height=14,image=image_path2)
label_Img2.place(x=150, y=10,width=64, height=44)
image_path3 = tk.PhotoImage(file = './data/icon4.png')
label_Img3 = tk.Label(win, width=64, height=14,image=image_path3)
label_Img3.place(x=220, y=10,width=64, height=44)
label_Img3.bind('<Button-1>',Checkimg)
label0 = tk.Label(win, text="加载总数:", font=('宋体', 12, 'bold'))
label0.place(x=510, y=65, height=30)
entry0 = tk.Entry(win, validate="focusout", bg='#F5F5F5')
entry0.place(x=510, y=90, width=60, height=30)
label1 = tk.Label(win, text="合格总数:", font=('宋体', 12, 'bold'))
label1.place(x=10, y=140, height=30)
entry1 = tk.Entry(win, validate="focusout", bg='#F5F5F5')
entry1.place(x=80, y=140, width=70, height=30)
# 图片容器
frame_right = tk.LabelFrame(win, labelanchor="w", bg='#D3D3D3')
frame_right.place(x=160, y=160, relwidth=0.35, relheight=0.35)
frame_right = tk.LabelFrame(win, labelanchor="w", bg='#D3D3D3')
# 使用 place 控制 LabelFrame 的位置
frame_right.place(x=380, y=160, relwidth=0.35, relheight=0.35)
# 单选框-药品选择类型
v = tk.IntVar()
label_text = tk.Label(win, text="请选择药品检测类型:", font=('宋体', 13, 'bold'))
label_text.place(x=10, y=60, height=40)
radio_button = tk.Radiobutton(win, text='药片检测', variable=v, value=0)
radio_button.place(x=150, y=60, width=90, height=40)
radio_button = tk.Radiobutton(win, text='胶囊检测', variable=v, value=1)
radio_button.place(x=150, y=90, width=90, height=35)
# 单选框-药品选择类型
v1 = tk.IntVar()
label_text = tk.Label(win, text="是否开启摄像头采样:", font=('宋体', 13, 'bold'))
label_text.place(x=270, y=60, height=40)
radio_button = tk.Radiobutton(win, text='关闭', variable=v1, value=0)
radio_button.place(x=410, y=60, width=90, height=40)
radio_button = tk.Radiobutton(win, text='开启', variable=v1, value=1)
radio_button.place(x=410, y=90, width=90, height=35)
# 数据结果显示
label_text = tk.Label(win, text="检测结果:", font=('宋体', 13, 'bold italic'))
label_text.place(x=10, y=340, height=40)
frame_result = tk.LabelFrame(win, labelanchor="w", bg='#F5F5F5')
frame_result.place(x=80, y=370, relwidth=0.85, relheight=0.25)
label_text = tk.Label(win, text="检测总数", font=('宋体', 15, 'bold italic'), bg='#F5F5F5')
label_text.place(x=90, y=380)
label_text = tk.Label(win, text="检测合格", font=('宋体', 15, 'bold italic'), bg='#F5F5F5')
label_text.place(x=190, y=380)
label_text = tk.Label(win, text="检测缺陷", font=('宋体', 15, 'bold italic'), bg='#F5F5F5')
label_text.place(x=290, y=380)
label_text = tk.Label(win, text="合格率", font=('宋体', 15, 'bold italic'), bg='#F5F5F5')
label_text.place(x=390, y=380)
label_text = tk.Label(win, text="模型识别率", font=('宋体', 15, 'bold italic'), bg='#F5F5F5')
label_text.place(x=470, y=380)
label_diff0 = tk.Label(win, text='药片', font=('宋体', 13,))
label_diff0.place(x=30, y=90)
label_diff1 = tk.Label(win, text='计数', font=('宋体', 13,))
label_diff1.place(x=290, y=90)
label_num1 = tk.Label(win, text='', font=('宋体', 20,), bg='#F5F5F5')
label_num1.place(x=110, y=420)
label_num2 = tk.Label(win, text='', font=('宋体', 20,), bg='#F5F5F5')
label_num2.place(x=210, y=420)
label_num3 = tk.Label(win, text='', font=('宋体', 20,), bg='#F5F5F5')
label_num3.place(x=310, y=420)
label_num4 = tk.Label(win, text='', font=('宋体', 20,), bg='#F5F5F5')
label_num4.place(x=380, y=420)
label_num5 = tk.Label(win, text='', font=('宋体', 20,), bg='#F5F5F5')
label_num5.place(x=480, y=420)
# 加载图片
button1 = tk.Button(win, text="选择导入", command=OpenImg)
button1.place(x=10, y=200, width=80, height=40)
# 数据可视化
button2 = tk.Button(win, text="数据可视化",command=Get)
button2.place(x=10, y=260, width=80, height=40)
# 确认按钮
button0 = tk.Button(win, text="开始检测", command=Showtext, bg="#D3D3D3", font=('宋体', 15, 'bold italic'))
button0.place(x=400, y=10, width=150, height=40)
win.mainloop()
开始检测函数
# 创建打开图像和显示图像函数
def OpenImg():
global img1
global Path
OpenFile = tk.Tk() # 创建新窗口
OpenFile.withdraw()
file_path = filedialog.askopenfilename()
Img = Image.open(file_path)
out = Img.resize((200, 200))
img1 = ImageTk.PhotoImage(out)
label_Img = tk.Label(win, width=200, height=150, image=img1)
label_Img.place(x=160, y=160, relwidth=0.35, relheight=0.35)
Path = file_path
# 确认检测函数
def Showtext():
if v.get() == 0:
label_diff0['text']='(药片-开始)'
if v1.get()==0:
if Delay() == 2:
value = Judgepian()
label_num1['text'] = value[0]
label_num2['text'] = value[1]
label_num3['text'] = value[2]
label_num4['text'] = str(value[1] / value[0] * 100)[:5] + '%'
global photo
photo = ImageTk.PhotoImage(file=value[3])
label_Img1 = tk.Label(win, image=photo)
label_Img1.place(x=380, y=160, relwidth=0.35, relheight=0.35)
if entry1.get() != '':
acc = value[1] / int(entry1.get())
if acc > 1:
label_num5['text'] = '出错'
if acc <= 1:
label_num5['text'] = str(acc * 100)[:5] + '%'
if entry1.get() == '':
label_num5['text'] = '未定义'
print('完好的药片;', value, entry1.get())
if v1.get() == 1:
global number0
import csv
number0 = int(entry0.get())
csvfile = open('./data/result.csv', 'w', encoding='utf-8', newline="")
fieldnames = ['序号', '检测总数', '检测合格', '检测缺陷', '合格率', '模型识别率','检测时间']
write = csv.DictWriter(csvfile, fieldnames=fieldnames)
write.writeheader()
for x in range(0, number0):
global photo1
global Path
global count_num
count_num = count_num + 1
Path = Start_camera()
time.sleep(1)
Img = Image.open(Path)
out = Img.resize((200, 200))
img1 = ImageTk.PhotoImage(out)
label_Img0 = tk.Label(win, width=200, height=150, image=img1)
label_Img0.image = img1
label_Img0.place(x=160, y=160, relwidth=0.35, relheight=0.35)
win.update()
time.sleep(0.5)
value = Judgepian()
label_num1['text'] = value[0]
label_num2['text'] = value[1]
label_num3['text'] = value[2]
label_num4['text'] = str(value[1] / value[0] * 100)[:5] + '%'
photo1 = ImageTk.PhotoImage(file=value[3])
label_Img1 = tk.Label(win, image=photo1)
label_Img1.place(x=380, y=160, relwidth=0.35, relheight=0.35)
win.update()
if entry1.get() != '':
acc = value[1] / int(entry1.get())
if acc > 1:
label_num5['text'] = '出错'
rnum = '出错'
if acc <= 1:
label_num5['text'] = str(acc * 100)[:5] + '%'
rnum = str(acc * 100)[:5] + '%'
if entry1.get() == '':
label_num5['text'] = '未定义'
rnum = '未定义'
now_time = time.strftime('%Y-%m.%d-%H:%M:%S', time.localtime(time.time()))
write.writerow({'序号':count_num,'检测总数': value[0],'检测合格': value[1],'检测缺陷': value[2],'合格率': str(value[1] / value[0] * 100)[:5] + '%','模型识别率': rnum,'检测时间':now_time})
label_diff1['text'] = '(第'+str(count_num)+'次完成)'
if v.get() == 1:
label_diff0['text']= '胶囊'
print('12344')
label_diff0 = tk.Label(win, text='药片', font=('宋体', 13,))
label_diff0.place(x=30, y=90)
label_diff1 = tk.Label(win, text='计数', font=('宋体', 13,))
label_diff1.place(x=290, y=90)
label_num1 = tk.Label(win, text='', font=('宋体', 20,), bg='#F5F5F5')
label_num1.place(x=110, y=420)
label_num2 = tk.Label(win, text='', font=('宋体', 20,), bg='#F5F5F5')
label_num2.place(x=210, y=420)
label_num3 = tk.Label(win, text='', font=('宋体', 20,), bg='#F5F5F5')
label_num3.place(x=310, y=420)
label_num4 = tk.Label(win, text='', font=('宋体', 20,), bg='#F5F5F5')
label_num4.place(x=380, y=420)
label_num5 = tk.Label(win, text='', font=('宋体', 20,), bg='#F5F5F5')
label_num5.place(x=480, y=420)
def Delay(i=0):
for x in range(0, 2):
if i < 2:
i = i + 1
time.sleep(1)
return i
打包说明
1.第三方库,要自己安装:
pip install pyinstaller
2.将Python程序打包成标准的可执行文件,这些文件可以在没有安装Python的计算机上运行。支持 win、linux、Mac OS;
3.为了使打包的程序尽可能更小,推荐创建一个虚拟环境;
打包指令:>>
pyinstaller -n Tmodel -w -p ./env -i ./data/favicon.ico main.py
若需要源码请关注微信公众号:兴趣学习社