AI智能联系人管理系统(一)

tech2024-01-23  67

前段时间练习过的一个小项目,今天再看看,记录一下~

开发工具准备:

开发工具:PyCharm

Python内置模块:sys、os、base64、json、collections

第三方模块:PyQt5、requests、pandas、Pillow(PIL)、phone、pyecharts

PyQt5模块:实现项目窗体设计 pyecharts模块:绘制分布饼图

项目组织结构:

说明:

res文件夹:是资源文件夹,里面包含三个文件夹。datafile文件夹保存的是联系人的信息表和联系人分布饼图;img文件夹是保存图片的;ui文件夹保存的是使用Qt Designer工具设计的各种窗体ui文件。Qt Designer的配置参考https://blog.csdn.net/wang_hugh/article/details/88775868addpage.py、editpage.py、gridlayout.py、mainpage.py文件都是由对应的.ui文件使用Pyuic工具转换而来的。其中addpage.ui是添加联系人信息界面;editpage.ui是编辑联系人信息界面;gridlayout.ui是联系人信息展示界面;mainpage.ui是主窗体设计文件card_gray.jpg文件:是名片识别的灰度图card_main.py文件:程序主文件key.txt文件:申请汉王云名片识别接口的keypinyintool.py文件:判断汉字首字母模块文件

项目实现的功能:

添加联系人:两种方法添加联系人,一种是通过识别名片添加联系人信息,另一种是通过手动添加联系人信息;然后将联系人信息写到文档里搜索联系人:两种方式搜索,一是关键词搜索,二是按照首字母搜索编辑联系人信息删除联系人信息查看联系人分布:生成饼状图

系统窗体以及添加联系人信息页面的实现

通过Qt Designer工具设计四个界面,效果如下:

①AI智能联系人管理主页面

② 添加联系人信息页面

③编辑联系人信息界面

④展示联系人信息界面

创建card_main.py文件,初始化页面主页并显示,代码如下:(显示Qt Designer工具设计的界面基本都是这个写法)

#主窗体页面 import sys from PyQt5.QtWidgets import QWidget, QApplication import mainpage class parentWindow(QWidget,mainpage.Ui_Form): # 初始化方法 def __init__(self): # 找到父类主窗体页面 super(parentWindow,self).__init__() # 初始化页面方法 self.setupUi(self) if __name__=='__main__': # 每一个 PyQt5应用都必须创建一个应用对象 app=QApplication(sys.argv) # 初始化页面 window=parentWindow() # 显示主窗体 window.show() # 项目结束调用 sys.exit(app.exec_())

点击主窗体的“添加”按钮,显示添加联系人界面。在card_main.py文件中新建childWindow类,初始化页面并建立OPEN()方法,用于显示添加联系人界面,然后在主方法中初始化childWindow类,并且为“添加”按钮添加事件,代码如下:

#主窗体页面 import sys from PyQt5.QtWidgets import QWidget, QApplication import addpage import mainpage class parentWindow(QWidget,mainpage.Ui_Form): # 初始化方法 def __init__(self): # 找到父类主窗体页面 super(parentWindow,self).__init__() # 初始化页面方法 self.setupUi(self) #添加联系人页面 class childWindow(QWidget,addpage.Ui_Form): def __init__(self): # 找到父类 添加联系人页面 super(childWindow,self).__init__() # 初始化页面 self.setupUi(self) #显示添加联系人页面 def OPEN(self): #显示页面 self.show() if __name__=='__main__': # 每一个 PyQt5应用都必须创建一个应用对象 app=QApplication(sys.argv) # 初始化页面 window=parentWindow() # 显示主窗体 window.show() child = childWindow() # 添加页面 window.pushButton_2.clicked.connect(child.OPEN) # 添加按钮事件 # 项目结束调用 sys.exit(app.exec_())

运行效果如图:

创建保存数据文件:(pandas模块)

智能停车场车牌识别系统(一)也有这一部分的实现,写法基本类似。

该项目需要创建一个用于保存联系人信息的表,主要用到pandas模块和os模块。关键代码如下:

import os import pandas as pd cdir=os.getcwd() path=cdir+'/res/datafile/' #建立名片信息表 if not os.path.exists(path): # 建立文件夹 os.makedirs(path) # 姓名 公司 电话 手机 邮件 地址 城市 分类 cardfile=pd.DataFrame(columns=['name','comp','tel','mobile','email','addr','city','type']) # 生成.xlsx文件 cardfile.to_excel(path+'名片信息表.xlsx',sheet_name='data',index=None)

运行效果如图:

识别名片:(核心功能)

申请汉王云名片识别接口key

汉王云名片接口 API申请地址:http://developer.hanvon.com/。进入官网,点击右上角进行登录或注册

登录成功之后,依次点击【开发中心】→【应用管理】,点击右上角的【创建应用】

里面填写的内容参考如下:

再进入到【开发中心】→【应用管理】,点击右边的【Key管理】,进入之后点击【生成服务器key】,点击之后直接点里面的【生成】按钮,不用填写里面的 服务器IP地址白名单。

完成之后会生成Key,界面如下:

将申请的key写到项目根目录下的key.txt文件中。

实现识别名片功能

在childWindow类中创建openfile()方法,该方法是点击添加名片界面里面的“选择名片”按钮触发的方法。先通过QFileDialog.getOpenFileName()方法打开选择文件对话框,选择要识别的名片图片,再调用recg()方法识别名片图片,返回识别结果。如果返回的结果中’code’为0的话,说明返回正确信息,再调用dcontent()方法把信息显示到对应的文本框里面。openfile()方法代码如下:

# 选择名片的按钮执行方法 def openfile(self): # 启动选择文件对话框,查找jpg以及png图片 self.download_path = QFileDialog.getOpenFileName(self, "选择要识别的名片图片", "./res/img", "Image Files(*.jpg *.png)") if not self.download_path[0].strip(): # 判断是否选择图片 # 消息对话框 information 提问对话框 question 警告对话框 warning # 严重错误对话框 critical 关于对话框 about QMessageBox.information(self, '提示信息', '没有选择名片图片') else: pixmap = QPixmap(self.download_path[0]) # self.download_path[0]为图片路径,pixmap解析图片 # print(pixmap) self.label.setPixmap(pixmap) # 设置图片 self.label.setScaledContents(True) # 让图片自适应大小 try: content = self.recg() # 识别名片图片,返回识别结果 except: QMessageBox.information(self, '提示信息', '识别错误,请重新选择图片!') cjson = json.loads(content) print(cjson) if cjson['code'] == '0': # 判断是否正确返回内容 self.dcontent(1, cjson) # 名称 self.dcontent(2, cjson) # 公司 self.dcontent(3, cjson) # 电话 self.dcontent(4, cjson) # 手机 self.dcontent(5, cjson) # 邮件 self.dcontent(6, cjson) # 地址 else: QMessageBox.information(self, '提示信息', '信息码-' + cjson[ 'code'] + ' 请去官网http://developer.hanvon.com/api/toAPIinfo.do?id=2&num= 查看原因')

在childWindow类中创建recg()方法,这个方法主要用于处理对选择的图片进行图片识别,返回联系人信息。汉王云官网会有代码示例,网址为:http://developer.hanvon.com/api/toAPIinfo.do?id=2,里面有很多内容,还可以在线体验。该项目的请求接口选择的是多语言带坐标。代码如下:

#识别名片图片 def recg(self): with open('key.txt','r') as file: key=file.readline() #读取写到key.txt文件中的您申请的key #print(key) url='http://api.hanvon.com/rt/ws/v1/ocr/bcard/recg?key=%s&code=cf22e3bb-d41c-47e0-aa44-a92984f5829d' % key img=Image.open(self.download_path[0]) img2=img.convert('L') _w=img2.width _h=img2.height img2=img2.resize((int(_w),int(_h)),Image.ANTIALIAS) img2.save('card_gray.jpg') base64img=base64.b64encode(open('card_gray.jpg','rb').read()).decode() data={"lang":'auto',"color":'gray',"image":base64img} headers={"Content-Type":"application/octet-stream"} resp=requests.post(url,data=json.dumps(data),headers=headers) return resp.text

card_main.py整体代码如下:

#主窗体页面 import base64 import json import sys import os import pandas as pd import requests from PIL import Image # qt5模块 from PyQt5.QtWidgets import * from PyQt5.QtGui import * import addpage import mainpage cdir=os.getcwd() path=cdir+'/res/datafile/' #建立名片信息表 if not os.path.exists(path): # 建立文件夹 os.makedirs(path) # 姓名 公司 电话 手机 邮件 地址 城市 分类 cardfile=pd.DataFrame(columns=['name','comp','tel','mobile','email','addr','city','type']) # 生成.xlsx文件 cardfile.to_excel(path+'名片信息表.xlsx',sheet_name='data',index=None) class parentWindow(QWidget,mainpage.Ui_Form): # 初始化方法 def __init__(self): # 找到父类主窗体页面 super(parentWindow,self).__init__() # 初始化页面方法 self.setupUi(self) #添加联系人页面 class childWindow(QWidget,addpage.Ui_Form): def __init__(self): # 找到父类 添加联系人页面 super(childWindow,self).__init__() # 初始化页面 self.setupUi(self) self.pushButton.clicked.connect(self.openfile) # 给选择名片按钮添加事件 # 显示添加联系人页面 def OPEN(self): self.label.setPixmap(QPixmap("")) # 移除控件上图片 # 移除输入框内容 self.lineEdit_1.setText("") self.lineEdit_2.setText("") self.lineEdit_3.setText("") self.lineEdit_4.setText("") self.lineEdit_5.setText("") self.lineEdit_6.setText("") # 显示页面 self.show() # 选择名片的按钮执行方法 def openfile(self): # 启动选择文件对话框,查找jpg以及png图片 self.download_path = QFileDialog.getOpenFileName(self, "选择要识别的名片图片", "./res/img", "Image Files(*.jpg *.png)") if not self.download_path[0].strip(): # 判断是否选择图片 # 消息对话框 information 提问对话框 question 警告对话框 warning # 严重错误对话框 critical 关于对话框 about QMessageBox.information(self, '提示信息', '没有选择名片图片') else: pixmap = QPixmap(self.download_path[0]) # self.download_path[0]为图片路径,pixmap解析图片 # print(pixmap) self.label.setPixmap(pixmap) # 设置图片 self.label.setScaledContents(True) # 让图片自适应大小 try: content = self.recg() # 识别名片图片,返回识别结果 except: QMessageBox.information(self, '提示信息', '识别错误,请重新选择图片!') cjson = json.loads(content) print(cjson) if cjson['code'] == '0': # 判断是否正确返回内容 self.dcontent(1, cjson) # 名称 self.dcontent(2, cjson) # 公司 self.dcontent(3, cjson) # 电话 self.dcontent(4, cjson) # 手机 self.dcontent(5, cjson) # 邮件 self.dcontent(6, cjson) # 地址 else: QMessageBox.information(self, '提示信息', '信息码-' + cjson[ 'code'] + ' 请去官网http://developer.hanvon.com/api/toAPIinfo.do?id=2&num= 查看原因') # 识别名片图片 def recg(self): with open('key.txt', 'r') as file: key = file.readline() # 读取写到key.txt文件中的您申请的key # print(key) url = 'http://api.hanvon.com/rt/ws/v1/ocr/bcard/recg?key=%s&code=cf22e3bb-d41c-47e0-aa44-a92984f5829d' % key img = Image.open(self.download_path[0]) img2 = img.convert('L') _w = img2.width _h = img2.height img2 = img2.resize((int(_w), int(_h)), Image.ANTIALIAS) img2.save('card_gray.jpg') base64img = base64.b64encode(open('card_gray.jpg', 'rb').read()).decode() data = {"lang": 'auto', "color": 'gray', "image": base64img} headers = {"Content-Type": "application/octet-stream"} resp = requests.post(url, data=json.dumps(data), headers=headers) return resp.text # 设置识别显示的内容 def dcontent(self, k, count): try: if k == 1: self.lineEdit_1.setText(count['name'][0]) elif k == 2: self.lineEdit_2.setText(count['comp'][0]) elif k == 3: self.lineEdit_3.setText(count['tel'][0]) elif k == 4: self.lineEdit_4.setText(count['mobile'][0]) elif k == 5: self.lineEdit_5.setText(count['email'][0]) elif k == 6: self.lineEdit_6.setText(count['addr'][0]) except: pass if __name__=='__main__': # 每一个 PyQt5应用都必须创建一个应用对象 app=QApplication(sys.argv) # 初始化页面 window=parentWindow() # 显示主窗体 window.show() child = childWindow() # 添加页面 window.pushButton_2.clicked.connect(child.OPEN) # 添加按钮事件 # 项目结束调用 sys.exit(app.exec_())

运行效果如图: 名片识别成功后,返回的内容如下:

{'code': '0', 'result': None, 'rotatedAngle': '0.0', 'name': ['赵云帆', '466', '224', '796', '313'], 'title': ['总经理', '549', '362', '708', '402'], 'tel': ['0109959179', '374', '460', '642', '485'], 'mobile': [], 'fax': ['0109959176', '372', '497', '642', '523'], 'email': ['zhaoyunfan@hanwang.com', '373', '537', '869', '565'], 'comp': ['汉王科技股份有限公司', '254', '58', '864', '117'], 'dept': [], 'degree': [], 'addr': ['中关村软件园汉王科技', '372', '572', '739', '598'], 'post': [], 'mbox': [], 'htel': [], 'web': [], 'im': [], 'numOther': [], 'other': [], 'extTel': []}

保存名片信息到文件中

上面已经实现了对名片的识别,识别之后需要保存。对信息的保存,主要是保存名片信息到文档中。添加完名片信息之后,点击“保存”按钮,会把名片信息保存到 名片信息表.xlsx 文件中。在childWindow类中创建keep()方法,首先获取输入框内容,根据手机号判断所属区域;接着判断姓名不能为空,根据姓名获取首字母拼音(后面要实现根据首字母进行搜索);最后将名片信息添加到 名片信息表.xlsx 文件中。keep()方法代码如下:

# 保存名片信息到文档 def keep(self): pi_table = pd.read_excel(path + '名片信息表.xlsx', sheet_name='data') # 获取输入框内容 name = self.lineEdit_1.text() comp = self.lineEdit_2.text() tel = self.lineEdit_3.text() mobile = self.lineEdit_4.text() email = self.lineEdit_5.text() addr = self.lineEdit_6.text() # 判断电话是否为空 if mobile.strip(): info = phone.Phone().find(int(mobile)) # 根据电话号判断区域 # print(info) if info == None: city = '其他' else: city = info['province'] else: city = '其他' # 判断姓名是否为空 if name.strip(): type = pinyintool.getPinyin(name[0]) # 获取首字母拼音 # 添加数据 data = pi_table.append({'name': name, 'comp': comp, 'tel': tel, 'mobile': mobile, 'email': email, 'addr': addr, 'city': city, 'type': type, }, ignore_index=True) # 更新xlsx文件 DataFrame(data).to_excel(path + '名片信息表.xlsx', sheet_name='data', index=False) window.dataall() # 主窗体显示全部数据 self.close() # 关闭添加页面 else: QMessageBox.information(self, '提示信息', '姓名不能为空')

pinyintool.py代码如下:(通过姓名获取首字母大写)

def single_get_first(unicode1): str1 = unicode1.encode('gbk') try: ord(str1) return str1 except: asc = str1[0] * 256 + str1[1] - 65536 if asc >= -20319 and asc <= -20284: return 'A' if asc >= -20283 and asc <= -19776: return 'B' if asc >= -19775 and asc <= -19219: return 'C' if asc >= -19218 and asc <= -18711: return 'D' if asc >= -18710 and asc <= -18527: return 'E' if asc >= -18526 and asc <= -18240: return 'F' if asc >= -18239 and asc <= -17923: return 'G' if asc >= -17922 and asc <= -17418: return 'H' if asc >= -17417 and asc <= -16475: return 'J' if asc >= -16474 and asc <= -16213: return 'K' if asc >= -16212 and asc <= -15641: return 'L' if asc >= -15640 and asc <= -15166: return 'M' if asc >= -15165 and asc <= -14923: return 'N' if asc >= -14922 and asc <= -14915: return 'O' if asc >= -14914 and asc <= -14631: return 'P' if asc >= -14630 and asc <= -14150: return 'Q' if asc >= -14149 and asc <= -14091: return 'R' if asc >= -14090 and asc <= -13319: return 'S' if asc >= -13318 and asc <= -12839: return 'T' if asc >= -12838 and asc <= -12557: return 'W' if asc >= -12556 and asc <= -11848: return 'X' if asc >= -11847 and asc <= -11056: return 'Y' if asc >= -11055 and asc <= -10247: return 'Z' return '' def getPinyin(string): if string == None: return None if not '\u4e00' <= string <= '\u9fff': return None lst = list(string) charLst = [] for l in lst: charLst.append(single_get_first(l)) return ''.join(charLst)

在childWindow类中的 _ _ init _ _( self ) 方法中要给“保存”按钮添加keep事件:

self.pushButton_2.clicked.connect(self.keep) # 给保存按钮添加事件

把上面识别的名片信息保存之后,内容如下:

主窗体显示联系人信息

上面内容已经把名片信息保存到了文件中,根据名片信息表的内容与设计的展示名片信息的列表控件,实现主窗体显示联系人信息的功能。首先新建griditem类,主要用于初始化列表样式页面,然后在页面初始化类parentWindow中创建dataall()方法,用于读取联系人信息,并显示到页面上。在dataall()方法里面,每次先循环删除管理器中的组件,然后读取文件内容,循环显示到页面中,每行三个。card_main.py整体代码如下:

# qt5模块 from PyQt5.QtWidgets import * from PyQt5.QtGui import * # 自定义模块 import gridlayout import mainpage import addpage import pinyintool # 内置模块 import sys import requests, base64, json import os # 第三方模块 import pandas as pd from pandas import DataFrame from PIL import Image import phone cdir=os.getcwd() path=cdir+'/res/datafile/' #建立名片信息表 if not os.path.exists(path): # 建立文件夹 os.makedirs(path) # 姓名 公司 电话 手机 邮件 地址 城市 分类 cardfile=pd.DataFrame(columns=['name','comp','tel','mobile','email','addr','city','type']) # 生成.xlsx文件 cardfile.to_excel(path+'名片信息表.xlsx',sheet_name='data',index=None) #主窗体列表样式 class griditem(QWidget,gridlayout.Ui_Form): def __init__(self): #初始化方法 super(griditem,self).__init__() #找到父类主窗体页面 self.setupUi(self) #初始化页面方法 #主窗体页面 class parentWindow(QWidget,mainpage.Ui_Form): # 初始化方法 def __init__(self): # 找到父类主窗体页面 super(parentWindow,self).__init__() # 初始化页面方法 self.setupUi(self) self.dataall() # 显示全部数据 def dataall(self): # 每次先循环删除管理器的组件 while self.gridLayout.count(): item = self.gridLayout.takeAt(0) # 获取第一个组件 widget = item.widget() widget.deleteLater() # 删除组件 i = -1 pi_table = pd.read_excel(path + '名片信息表.xlsx', sheet_name='data') # 读取文件内容 cardArray = pi_table.values # 获取所有数据 for n in range(len(cardArray)): x = n % 3 # x确定每行显示的个数0,1,2,每行三个 if x == 0: # 当x为0的时候设置换行即行数+1 i += 1 item = griditem() # 创建 主窗体列表样式 类 的实例 item.label_1.setText('姓名:' + str(cardArray[n][0])) item.label_2.setText('公司:' + str(cardArray[n][1])) item.label_3.setText('电话:' + str(cardArray[n][2])) item.label_4.setText('手机:' + str(cardArray[n][3])) item.label_5.setText('邮箱:' + str(cardArray[n][4])) item.label_6.setText('地址:' + str(cardArray[n][5])) # 设置名称 为获取项目行数 item.pushButton.setObjectName(str(pi_table.index.tolist()[n])) item.pushButton_1.setObjectName(str(pi_table.index.tolist()[n])) # 为按钮绑定事件 #item.pushButton.clicked.connect(self.edit) # 编辑 #item.pushButton_1.clicked.connect(self.deletedata) # 删除 self.gridLayout.addWidget(item, i, x) # 动态添加控件到gridLayout self.scrollAreaWidgetContents.setMinimumHeight(i * 200) # 设置上下滑动控件可以滑动 self.scrollAreaWidgetContents.setLayout(self.gridLayout) # 设置gridLayout到滑动控件中 #添加联系人页面 class childWindow(QWidget,addpage.Ui_Form): def __init__(self): # 找到父类 添加联系人页面 super(childWindow,self).__init__() # 初始化页面 self.setupUi(self) self.pushButton.clicked.connect(self.openfile) # 给选择名片按钮添加事件 self.pushButton_2.clicked.connect(self.keep) # 给保存按钮添加事件 # 显示添加联系人页面 def OPEN(self): self.label.setPixmap(QPixmap("")) # 移除控件上图片 # 移除输入框内容 self.lineEdit_1.setText("") self.lineEdit_2.setText("") self.lineEdit_3.setText("") self.lineEdit_4.setText("") self.lineEdit_5.setText("") self.lineEdit_6.setText("") # 显示页面 self.show() # 选择名片的按钮执行方法 def openfile(self): # 启动选择文件对话框,查找jpg以及png图片 self.download_path = QFileDialog.getOpenFileName(self, "选择要识别的名片图片", "./res/img", "Image Files(*.jpg *.png)") if not self.download_path[0].strip(): # 判断是否选择图片 # 消息对话框 information 提问对话框 question 警告对话框 warning # 严重错误对话框 critical 关于对话框 about QMessageBox.information(self, '提示信息', '没有选择名片图片') else: pixmap = QPixmap(self.download_path[0]) # self.download_path[0]为图片路径,pixmap解析图片 # print(pixmap) self.label.setPixmap(pixmap) # 设置图片 self.label.setScaledContents(True) # 让图片自适应大小 try: content = self.recg() # 识别名片图片,返回识别结果 except: QMessageBox.information(self, '提示信息', '识别错误,请重新选择图片!') cjson = json.loads(content) print(cjson) if cjson['code'] == '0': # 判断是否正确返回内容 self.dcontent(1, cjson) # 名称 self.dcontent(2, cjson) # 公司 self.dcontent(3, cjson) # 电话 self.dcontent(4, cjson) # 手机 self.dcontent(5, cjson) # 邮件 self.dcontent(6, cjson) # 地址 else: QMessageBox.information(self, '提示信息', '信息码-' + cjson[ 'code'] + ' 请去官网http://developer.hanvon.com/api/toAPIinfo.do?id=2&num= 查看原因') # 识别名片图片 def recg(self): with open('key.txt', 'r') as file: key = file.readline() # 读取写到key.txt文件中的您申请的key # print(key) url = 'http://api.hanvon.com/rt/ws/v1/ocr/bcard/recg?key=%s&code=cf22e3bb-d41c-47e0-aa44-a92984f5829d' % key img = Image.open(self.download_path[0]) img2 = img.convert('L') _w = img2.width _h = img2.height img2 = img2.resize((int(_w), int(_h)), Image.ANTIALIAS) img2.save('card_gray.jpg') base64img = base64.b64encode(open('card_gray.jpg', 'rb').read()).decode() data = {"lang": 'auto', "color": 'gray', "image": base64img} headers = {"Content-Type": "application/octet-stream"} resp = requests.post(url, data=json.dumps(data), headers=headers) return resp.text # 设置识别显示的内容 def dcontent(self, k, count): try: if k == 1: self.lineEdit_1.setText(count['name'][0]) elif k == 2: self.lineEdit_2.setText(count['comp'][0]) elif k == 3: self.lineEdit_3.setText(count['tel'][0]) elif k == 4: self.lineEdit_4.setText(count['mobile'][0]) elif k == 5: self.lineEdit_5.setText(count['email'][0]) elif k == 6: self.lineEdit_6.setText(count['addr'][0]) except: pass # 保存名片信息到文档 def keep(self): pi_table = pd.read_excel(path + '名片信息表.xlsx', sheet_name='data') # 获取输入框内容 name = self.lineEdit_1.text() comp = self.lineEdit_2.text() tel = self.lineEdit_3.text() mobile = self.lineEdit_4.text() email = self.lineEdit_5.text() addr = self.lineEdit_6.text() # 判断电话是否为空 if mobile.strip(): info = phone.Phone().find(int(mobile)) # 根据电话号判断区域 # print(info) if info == None: city = '其他' else: city = info['province'] else: city = '其他' # 判断姓名是否为空 if name.strip(): type = pinyintool.getPinyin(name[0]) # 获取首字母拼音 # 添加数据 data = pi_table.append({'name': name, 'comp': comp, 'tel': tel, 'mobile': mobile, 'email': email, 'addr': addr, 'city': city, 'type': type, }, ignore_index=True) # 更新xlsx文件 DataFrame(data).to_excel(path + '名片信息表.xlsx', sheet_name='data', index=False) window.dataall() # 主窗体显示全部数据 self.close() # 关闭添加页面 else: QMessageBox.information(self, '提示信息', '姓名不能为空') if __name__=='__main__': # 每一个 PyQt5应用都必须创建一个应用对象 app=QApplication(sys.argv) # 初始化页面 window=parentWindow() # 显示主窗体 window.show() child = childWindow() # 添加页面 window.pushButton_2.clicked.connect(child.OPEN) # 添加按钮事件 # 项目结束调用 sys.exit(app.exec_())

运行效果如图:

再识别其他名片之后,点击“保存”按钮,主窗体会显示刚才识别的名片信息:

此时该项目的核心内容已经实现了,感觉篇幅有些长了。其他内容在下一篇实现! 链接:AI智能联系人管理系统(二) 转载请注明链接出处,谢谢! 自己完成的一个小项目,记录一下吧。 有什么问题或者需要源代码的,可以评论。我看到的就会回复!!!

最新回复(0)