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

Wesley13
• 阅读 1066

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

开发工具准备:

  • 开发工具:PyCharm

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

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

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

项目组织结构:

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

  • res文件夹:是资源文件夹,里面包含三个文件夹。datafile文件夹保存的是联系人的信息表和联系人分布饼图;img文件夹是保存图片的;ui文件夹保存的是使用Qt Designer工具设计的各种窗体ui文件。Qt Designer的配置参考https://blog.csdn.net/wang_hugh/article/details/88775868
  • addpage.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文件:申请汉王云名片识别接口的key
  • pinyintool.py文件:判断汉字首字母模块文件

项目实现的功能:

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

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

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

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

AI智能联系人管理系统(一)
② 添加联系人信息页面

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

③编辑联系人信息界面

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

④展示联系人信息界面

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_())
    

运行效果如图:

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

创建保存数据文件:(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)

运行效果如图:

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

识别名片:(核心功能)

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

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

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

  3. 里面填写的内容参考如下:
    AI智能联系人管理系统(一)

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

  5. 完成之后会生成Key,界面如下:
    AI智能联系人管理系统(一)

将申请的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_())
    

运行效果如图:
AI智能联系人管理系统(一)
名片识别成功后,返回的内容如下:

{'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)  # 给保存按钮添加事件

把上面识别的名片信息保存之后,内容如下:
AI智能联系人管理系统(一)

主窗体显示联系人信息

上面内容已经把名片信息保存到了文件中,根据名片信息表的内容与设计的展示名片信息的列表控件,实现主窗体显示联系人信息的功能。首先新建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智能联系人管理系统(一)
再识别其他名片之后,点击“保存”按钮,主窗体会显示刚才识别的名片信息:

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

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

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

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
2年前
Java获得今日零时零分零秒的时间(Date型)
publicDatezeroTime()throwsParseException{    DatetimenewDate();    SimpleDateFormatsimpnewSimpleDateFormat("yyyyMMdd00:00:00");    SimpleDateFormatsimp2newS
Stella981 Stella981
2年前
Python之time模块的时间戳、时间字符串格式化与转换
Python处理时间和时间戳的内置模块就有time,和datetime两个,本文先说time模块。关于时间戳的几个概念时间戳,根据1970年1月1日00:00:00开始按秒计算的偏移量。时间元组(struct_time),包含9个元素。 time.struct_time(tm_y
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
2个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这