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

tech2026-01-14  13

请先阅读:AI智能联系人管理系统(一)

在上篇文章的基础上,该篇文章主要完成三个功能:

编辑和删除联系人信息搜索联系人信息(关键字搜索、首字母搜索)查看联系人分布饼图

编辑和删除联系人信息

在parentWindow类的dataall()方法的for循环中为每一个“编辑”和“删除”按钮绑定事件:

#为按钮绑定事件 item.pushButton.clicked.connect(self.edit) #编辑 item.pushButton_1.clicked.connect(self.deletedata) #删除

编辑联系人信息

新建editWindow类,初始化页面并在其中建立OPEN()方法,用于显示编辑联系人信息界面。为编辑联系人信息界面的“保存”按钮添加保存信息事件,创建editkeep()方法,保存数据到文件中(editkeep()方法和childWindow类中的keep()方法很相似)

editWindow类的代码如下:

#编辑页面 class editWindow(QWidget,editpage.Ui_Form): #初始化方法 def __init__(self): super(editWindow,self).__init__() #找到父类,首页面 self.setupUi(self) #初始化页面方法 #为保存按钮添加事件 self.pushButton_2.clicked.connect(self.editkeep) #显示添加名片页面 def OPEN(self): self.show() #显示页面 #保存编辑内容 def editkeep(self): indexName=self.pushButton_2.objectName() #获取按钮名称 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]) #获取首字母拼音 datas=pi_table.drop(index=[int(indexName)],axis=0) #添加数据 data=datas.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,'提示信息','姓名不能为空')

在主方法中初始化editWindow类

editWindow = editWindow() # 初始化编辑页面

在parentWindow类创建edit()方法,打开编辑信息的页面,并且将信息显示到文本框中

# 编辑数据 def edit(self): # 获取信息源 点击的按钮 sender = self.gridLayout.sender() indexName = sender.objectName() # 获取按钮名称 pi_table = pd.read_excel(path + '名片信息表.xlsx', sheet_name='data') # 根据行号 获取数据 cardArray = pi_table.iloc[[indexName]].values editWindow.OPEN() # 打开编辑页面 # 设置数据 editWindow.lineEdit_1.setText(str(cardArray[0][0])) editWindow.lineEdit_2.setText(str(cardArray[0][1])) editWindow.lineEdit_3.setText(str(cardArray[0][2])) editWindow.lineEdit_4.setText(str(cardArray[0][3])) editWindow.lineEdit_5.setText(str(cardArray[0][4])) editWindow.lineEdit_6.setText(str(cardArray[0][5])) # 设置按钮名称 editWindow.pushButton_2.setObjectName(str(indexName))

运行效果如图:

点击名片姓名为张三的“编辑”按钮:

对张三的信息进行修改:

点击保存按钮,发现张三的名片信息已经修改:

删除联系人信息

在parentWindow类创建deletedata()方法,在 名片信息表.xlsx文档中删除该名片信息,然后调用显示全部数据的dataall()方法。删除方法是根据行号进行删除,在上一篇实现dataall()方法中为“编辑”和“删除”按钮设置的名称就是每个信息的行数,方便执行编辑和删除操作

# 删除数据方法 def deletedata(self): sender = self.gridLayout.sender() # 获取信号源,点击按钮 indexName = sender.objectName() # 获取按钮名称 pi_table = pd.read_excel(path + '名片信息表.xlsx', sheet_name='data') data = pi_table.drop(index=[int(indexName)], axis=0) # 根据行号删除数据 DataFrame(data).to_excel(path + '名片信息表.xlsx', sheet_name='data', index=False) # 更新xlsx文件 self.dataall() # 显示全部数据

运行效果如图:

删除上面编辑的张三的信息之后,界面如图:

搜索联系人信息

搜索联系人,就是按照要求显示联系人的信息,也就是局部显示联系人信息,所以内容和parentWindow类dataall()方法中的内容很相似

用关键字搜索联系人信息

在parentWindow类的_ _ init _ _( )方法中,为“搜索”按钮绑定事件:

self.pushButton.clicked.connect(self.seachbtn)

在parentWindow类中创建seachbtn()方法,这个方法和parentWindow类dataall()方法中的内容很相似。主要就是从文档中提取的信息不同。该方法首先把用户名或者公司名包含搜索内容的信息筛选出来,然后在显示到窗体中

# 搜索功能 def seachbtn(self): pi_table = pd.read_excel(path + '名片信息表.xlsx', sheet_name='data') # 读取文件内容 seachk = self.lineEdit.text() # 查询数据 用户名和公司如果有一个包含搜索内容筛选出来 cardArray = pi_table[ (pi_table['name'].str.contains(seachk)) | (pi_table['comp'].str.contains(seachk))].values tb = pi_table[(pi_table['name'].str.contains(seachk)) | (pi_table['comp'].str.contains(seachk))] if len(cardArray) == 0: QMessageBox.information(self, '提示信息', '没有搜索内容') else: while self.gridLayout.count(): item = self.gridLayout.takeAt(0) # 获取第一个组件 widget = item.widget() widget.deleteLater() # 删除组件 i = -1 for n in range(len(cardArray)): x = n % 3 # x确定每行显示的个数0,1,2,每行三个 if x == 0: # 当x为0的时候设置换行即行数+1 i += 1 item = griditem() # print(item) 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(tb.index.tolist()[n])) item.pushButton_1.setObjectName(str(tb.index.tolist()[n])) # print(pi_table.index.tolist()) # 为按钮绑定事件 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到滑动控件中

运行效果如图:

运行的初始界面:

在搜索框中输入“王”之后显示的内容:

用首字母搜索联系人信息

在parentWindow类的_ _ init _ _( )方法中,为“ALL”按钮和“A”到“Z”按钮绑定事件:

self.pushButton_3.clicked.connect(self.dataall) self.pushButton_4.clicked.connect(lambda: self.dataother('A')) self.pushButton_6.clicked.connect(lambda: self.dataother('B')) self.pushButton_5.clicked.connect(lambda: self.dataother('C')) self.pushButton_7.clicked.connect(lambda: self.dataother('D')) self.pushButton_8.clicked.connect(lambda: self.dataother('E')) self.pushButton_9.clicked.connect(lambda: self.dataother('F')) self.pushButton_10.clicked.connect(lambda: self.dataother('G')) self.pushButton_11.clicked.connect(lambda: self.dataother('H')) self.pushButton_12.clicked.connect(lambda: self.dataother('I')) self.pushButton_13.clicked.connect(lambda: self.dataother('J')) self.pushButton_14.clicked.connect(lambda: self.dataother('K')) self.pushButton_15.clicked.connect(lambda: self.dataother('L')) self.pushButton_16.clicked.connect(lambda: self.dataother('M')) self.pushButton_17.clicked.connect(lambda: self.dataother('N')) self.pushButton_18.clicked.connect(lambda: self.dataother('O')) self.pushButton_19.clicked.connect(lambda: self.dataother('P')) self.pushButton_20.clicked.connect(lambda: self.dataother('Q')) self.pushButton_21.clicked.connect(lambda: self.dataother('R')) self.pushButton_22.clicked.connect(lambda: self.dataother('S')) self.pushButton_23.clicked.connect(lambda: self.dataother('T')) self.pushButton_24.clicked.connect(lambda: self.dataother('U')) self.pushButton_25.clicked.connect(lambda: self.dataother('V')) self.pushButton_26.clicked.connect(lambda: self.dataother('W')) self.pushButton_27.clicked.connect(lambda: self.dataother('X')) self.pushButton_28.clicked.connect(lambda: self.dataother('Y')) self.pushButton_29.clicked.connect(lambda: self.dataother('Z'))

“ALL”按钮是显示全部数据,调用的是dataall()方法。“A”到“Z”按钮显示的是局部数据,调用的是dataother()方法。在parentWindow类中创建dataother()方法,这个方法和dataall()方法很相似,不同的地方是dataother()方法先要从 名片信息表.xlsx 文件中获取符合条件的信息。

#显示部分数据 def dataother(self,typeAZ): 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[pi_table['type']==typeAZ].values #获取数据 tb = pi_table[pi_table['type'] == typeAZ] for n in range(len(cardArray)): x=n%3 #x确定每行显示的个数0,1,2,每行三个 if x==0: #当x为0的时候设置换行即行数+1 i+=1 item=griditem() #print(item) 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(tb.index.tolist()[n])) item.pushButton_1.setObjectName(str(tb.index.tolist()[n])) #print(pi_table.index.tolist()) #为按钮绑定事件 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到滑动控件中

运行效果如图:

点击“Z”按钮之后,运行效果如下:

查看联系人分布饼图

在parentWindow类的_ _ init _ _( )方法中,为“查看联系人分布”按钮绑定事件:

self.pushButton_30.clicked.connect(self.lookpie)

创建HtmlWindows类用于显示饼图,代码如下:

#显示饼图类 class HtmlWindows(QMainWindow): def __init__(self): super(QMainWindow,self).__init__() self.setGeometry(200,200,850,500) self.browser=QWebEngineView() def set(self,title,hurl): self.setWindowTitle(title) d=os.path.dirname(__file__) #项目路径 #print(d) url=d+'/res/datafile/'+hurl self.browser.load(QUrl(url)) self.setCentralWidget(self.browser)

在主方法中初始化HtmlWindows类

htmlwidows = HtmlWindows() # 显示饼图类

在parentWindow类中,创建lookpie方法,该方法主要用于根据city列的信息,生成饼图HTML文件并显示,代码如下:

#显示饼状图 def lookpie(self): pi_table=pd.read_excel(path+'名片信息表.xlsx',sheet_name='data') #读取文件内容 citattr=pi_table['city'].values #获取城市信息 if len(citattr)==0: #判断是否有城市信息 QMessageBox.information(self,'提示信息','没有联系人') return attr=[] # 存放城市(不重复) v1=[] # 出现次数 for i in citattr: if not i in attr: attr.append(i) #Counter(计数器)是对字典的补充,用于追踪值的出现次数 d=collections.Counter(citattr) #print(d) for k in attr: v1.append(d[k]) #print(v1) pie=Pie('联系人分布') pie.add(' ',attr,v1,is_label_show=True) pie.show_config() pie.render(path+'联系人分布饼图.html') htmlwidows.set('联系人分布','联系人分布饼图.html') #调用HtmlWindows类的set方法 htmlwidows.show()

运行效果如图:

card_main.py全部代码展示如下:

# qt5模块 from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5.QtWebEngineWidgets import * from PyQt5.QtCore import * # 自定义模块 import mainpage import addpage import gridlayout import editpage import pinyintool # 内置模块 import sys import requests, base64, json import collections import os # 第三方模块 import pandas as pd from pandas import DataFrame from PIL import Image import phone from pyecharts import Pie 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.pushButton_3.clicked.connect(self.dataall) self.pushButton_4.clicked.connect(lambda: self.dataother('A')) self.pushButton_6.clicked.connect(lambda: self.dataother('B')) self.pushButton_5.clicked.connect(lambda: self.dataother('C')) self.pushButton_7.clicked.connect(lambda: self.dataother('D')) self.pushButton_8.clicked.connect(lambda: self.dataother('E')) self.pushButton_9.clicked.connect(lambda: self.dataother('F')) self.pushButton_10.clicked.connect(lambda: self.dataother('G')) self.pushButton_11.clicked.connect(lambda: self.dataother('H')) self.pushButton_12.clicked.connect(lambda: self.dataother('I')) self.pushButton_13.clicked.connect(lambda: self.dataother('J')) self.pushButton_14.clicked.connect(lambda: self.dataother('K')) self.pushButton_15.clicked.connect(lambda: self.dataother('L')) self.pushButton_16.clicked.connect(lambda: self.dataother('M')) self.pushButton_17.clicked.connect(lambda: self.dataother('N')) self.pushButton_18.clicked.connect(lambda: self.dataother('O')) self.pushButton_19.clicked.connect(lambda: self.dataother('P')) self.pushButton_20.clicked.connect(lambda: self.dataother('Q')) self.pushButton_21.clicked.connect(lambda: self.dataother('R')) self.pushButton_22.clicked.connect(lambda: self.dataother('S')) self.pushButton_23.clicked.connect(lambda: self.dataother('T')) self.pushButton_24.clicked.connect(lambda: self.dataother('U')) self.pushButton_25.clicked.connect(lambda: self.dataother('V')) self.pushButton_26.clicked.connect(lambda: self.dataother('W')) self.pushButton_27.clicked.connect(lambda: self.dataother('X')) self.pushButton_28.clicked.connect(lambda: self.dataother('Y')) self.pushButton_29.clicked.connect(lambda: self.dataother('Z')) self.pushButton.clicked.connect(self.seachbtn) self.pushButton_30.clicked.connect(self.lookpie) 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到滑动控件中 # 编辑数据 def edit(self): # 获取信息源 点击的按钮 sender = self.gridLayout.sender() indexName = sender.objectName() # 获取按钮名称 pi_table = pd.read_excel(path + '名片信息表.xlsx', sheet_name='data') # 根据行号 获取数据 cardArray = pi_table.iloc[[indexName]].values editWindow.OPEN() # 打开编辑页面 # 设置数据 editWindow.lineEdit_1.setText(str(cardArray[0][0])) editWindow.lineEdit_2.setText(str(cardArray[0][1])) editWindow.lineEdit_3.setText(str(cardArray[0][2])) editWindow.lineEdit_4.setText(str(cardArray[0][3])) editWindow.lineEdit_5.setText(str(cardArray[0][4])) editWindow.lineEdit_6.setText(str(cardArray[0][5])) # 设置按钮名称 editWindow.pushButton_2.setObjectName(str(indexName)) # 删除数据方法 def deletedata(self): sender = self.gridLayout.sender() # 获取信号源,点击按钮 indexName = sender.objectName() # 获取按钮名称 pi_table = pd.read_excel(path + '名片信息表.xlsx', sheet_name='data') data = pi_table.drop(index=[int(indexName)], axis=0) # 根据行号删除数据 DataFrame(data).to_excel(path + '名片信息表.xlsx', sheet_name='data', index=False) # 更新xlsx文件 self.dataall() # 显示全部数据 # 搜索功能 def seachbtn(self): pi_table = pd.read_excel(path + '名片信息表.xlsx', sheet_name='data') # 读取文件内容 seachk = self.lineEdit.text() # 查询数据 用户名和公司如果有一个包含搜索内容筛选出来 cardArray = pi_table[ (pi_table['name'].str.contains(seachk)) | (pi_table['comp'].str.contains(seachk))].values tb = pi_table[(pi_table['name'].str.contains(seachk)) | (pi_table['comp'].str.contains(seachk))] if len(cardArray) == 0: QMessageBox.information(self, '提示信息', '没有搜索内容') else: while self.gridLayout.count(): item = self.gridLayout.takeAt(0) # 获取第一个组件 widget = item.widget() widget.deleteLater() # 删除组件 i = -1 for n in range(len(cardArray)): x = n % 3 # x确定每行显示的个数0,1,2,每行三个 if x == 0: # 当x为0的时候设置换行即行数+1 i += 1 item = griditem() # print(item) 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(tb.index.tolist()[n])) item.pushButton_1.setObjectName(str(tb.index.tolist()[n])) # print(pi_table.index.tolist()) # 为按钮绑定事件 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到滑动控件中 #显示部分数据 def dataother(self,typeAZ): 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') #读取文件内容 #print(pi_table) cardArray=pi_table[pi_table['type']==typeAZ].values #获取数据 #print(cardArray) tb = pi_table[pi_table['type'] == typeAZ] for n in range(len(cardArray)): x=n%3 #x确定每行显示的个数0,1,2,每行三个 if x==0: #当x为0的时候设置换行即行数+1 i+=1 item=griditem() #print(item) 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(tb.index.tolist()[n])) item.pushButton_1.setObjectName(str(tb.index.tolist()[n])) #print(pi_table.index.tolist()) #为按钮绑定事件 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到滑动控件中 #显示饼状图 def lookpie(self): pi_table=pd.read_excel(path+'名片信息表.xlsx',sheet_name='data') #读取文件内容 citattr=pi_table['city'].values #获取城市信息 if len(citattr)==0: #判断是否有城市信息 QMessageBox.information(self,'提示信息','没有联系人') return attr=[] # 存放城市(不重复) v1=[] # 出现次数 for i in citattr: if not i in attr: attr.append(i) #Counter(计数器)是对字典的补充,用于追踪值的出现次数 d=collections.Counter(citattr) #print(d) for k in attr: v1.append(d[k]) #print(v1) pie=Pie('联系人分布') pie.add(' ',attr,v1,is_label_show=True) pie.show_config() pie.render(path+'联系人分布饼图.html') htmlwidows.set('联系人分布','联系人分布饼图.html') #调用HtmlWindows类的set方法 htmlwidows.show() #添加联系人页面 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, '提示信息', '姓名不能为空') #编辑页面 class editWindow(QWidget,editpage.Ui_Form): #初始化方法 def __init__(self): super(editWindow,self).__init__() #找到父类,首页面 self.setupUi(self) #初始化页面方法 #为保存按钮添加事件 self.pushButton_2.clicked.connect(self.editkeep) #显示添加名片页面 def OPEN(self): self.show() #显示页面 #保存编辑内容 def editkeep(self): indexName=self.pushButton_2.objectName() #获取按钮名称 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]) #获取首字母拼音 datas=pi_table.drop(index=[int(indexName)],axis=0) #添加数据 data=datas.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,'提示信息','姓名不能为空') #显示饼图类 class HtmlWindows(QMainWindow): def __init__(self): super(QMainWindow,self).__init__() self.setGeometry(200,200,850,500) self.browser=QWebEngineView() def set(self,title,hurl): self.setWindowTitle(title) d=os.path.dirname(__file__) #项目路径 #print(d) url=d+'/res/datafile/'+hurl self.browser.load(QUrl(url)) self.setCentralWidget(self.browser) if __name__=='__main__': # 每一个 PyQt5应用都必须创建一个应用对象 app=QApplication(sys.argv) # 初始化页面 window=parentWindow() # 显示主窗体 window.show() child = childWindow() # 添加页面 editWindow = editWindow() # 初始化编辑页面 htmlwidows = HtmlWindows() # 显示饼图类 window.pushButton_2.clicked.connect(child.OPEN) # 添加按钮事件 # 项目结束调用 sys.exit(app.exec_())

转载请注明链接出处,谢谢! 自己完成的一个小项目,记录一下吧。 有什么问题或者需要源代码的,可以评论。我看到的就会回复!!!

最新回复(0)