一、目标
书接上文:,我们已经成功的使用python实现了基本的文字转换,那么我们需要使用一个ui界面来是的用户更加便捷的使用它。
二、环境搭建
python的ui包很多,笔者习惯使用PyQt包,目前最新的是5,其中比较常用的是QtCore(包含核心的非GUI的功能)QtGui(包含窗口系统、事件处理、文字类、基本绘图、2D图像)QtWidget(包含创建桌面应用的UI元素),具体功能可以参考官网模块文档以及C++具体实现的API文
老流程,来到python配置环境下
pip install PyQt5
三、界面设计
ps:手动书写代码基本只适合大神以及初步解除来学习了解基本运行内容的,毕竟非可视化的ui设计并不便捷,进阶玩法:使用qt designer设计保存为.ui文件然后使用vsconde或pycharm转换为.py文件后调用即可,有点类似C#。后续会写个基础入门级教程。
首先简单写个小框架:输出是一个空白界面,同时定MyWindow的类,界面的具体设置在这个类中定义
import sys
from PyQt5.QtWidgets import QApplication, QVBoxLayout, QWidget, QPushButton, QGroupBox, QMainWindow,QDesktopWidget,QHBoxLayout
from PyQt5.QtCore import Qt
class MyWindow(QWidget):
def __init__(self):
# 切记一定要调用父类的__init__方法,因为它里面有很多对UI空间的初始化操作
super().__init__()
self.setWindowTitle("catchmessage")
if __name__ == '__main__':
length = 1000
width = 700
app = QApplication(sys.argv)
#创建一个Qwidget子类
w = MyWindow()
w.show()
# 程序进行循环等待状态
app.exec()
我们想让这个窗口打开后就出现的屏幕的正中央,此时需要import QDesktopWidget模块,来获取可用桌面的中央位置,然后根据窗口长宽简单计算下坐标,我们定义一个函数来实现它
def center_move(self,length,width):
self.resize(length, width) # 限制大小
center_point = QDesktopWidget().availableGeometry().center()
# 获取屏幕可用区域的中央位置
x = center_point.x()
y = center_point.y()
winx = float(x) - length / 2
winy = float(y) - width / 2
self.move(int(winx), int(winy))
要实现基本的交互功能,我们需要通过上传按钮来获取需要上传的图片,下载按钮来获取处理过的文字信息,清除记录来重置img对象。如下,我们建立了两个box,一个采用垂直分布,一个采用水平分布,这样一个简单的UI界面就完成了。
class MyWindow(QWidget):
def __init__(self):
# 切记一定要调用父类的__init__方法,因为它里面有很多对UI空间的初始化操作
super().__init__()
self.init_ui()
def init_ui(self):
#在子类中调用父类的构造函数,即带哦用Qwidget的类
length = 400
width = 300
self.setWindowTitle("catchmessage")
layout = QVBoxLayout()
center_move(self,length,width)
box1 = QGroupBox("")
container = QVBoxLayout()#创建一个垂直布局器
btn1 = QPushButton('上传图片')
container.addWidget(btn1)
#上方区域使用垂直布局
box1.setLayout(container)
box2 = QGroupBox("")
h_layout = QHBoxLayout()#创建一个水平布局器
btn2 = QPushButton('进行识别')
btn3 = QPushButton('输出文件')
#将按钮添加到布局中
h_layout.addWidget(btn2)
h_layout.addWidget(btn3)
#下方区域使用水平布局
box2.setLayout(h_layout)
#将盒子1和2添加到layout布局
layout.addWidget(box1)
layout.addWidget(box2)
#让当前的窗口使用这个排列
self.setLayout(layout)
然后要做的就是添加关联事件,首先,我们要批量读取图像文件,并将文件的路径保存在全局变量Img中,便于后续操作
def file_load(self):
file_paths = QFileDialog.getOpenFileNames(None, "Select Image Files", "", "Images (*.png *.xpm *.jpg *.bmp)")
#file_path是一个元组,这个元组只有2个元素,[0]是list类型,存放路径[1]是str存放文件类型
if file_paths:
#利用全局变量来存放我们获得文件路径
global imgs
imgs = file_paths[0]
然后我们需要调.py文件中catchmessage函数,该函数能够实现输入图片对象,输出图片内的文字信息,我们定义一个do_catch函数来实现这个功能, 此时传入的参数Imgs是一个list,list列表里存储的是图片的地址,元素类型是str。当传入多个图片是,单线程工作会耗费大量的时间,所以我们定义一个threads_work函数来进行多线程运行,根据需求定义最大线程池为5.
def do_catch(self):
imgs = self.getimgs()
catch.threads_work(imgs)
def threads_work(imgs):
#设定最大线程数为5
max_threads = 5
semaphore = threading.Semaphore(max_threads)
threads = []
for img in imgs:
semaphore.acquire()
#线程调用对象为catchmessage,传入参数为 cv.imread(img),是一个图片对象
thread = threading.Thread(target=catchmassage, args=(cv2.imread(img),))
#thread = threading.Thread(target=catchmassage, args=(img,))
thread.start()
threads.append(thread)
#等待线程全部完成
for thread in threads:
thread.join()
最后将button关联事件
btn1 = QPushButton('上传图片',self)
btn1.clicked.connect(self.file_load)
btn2 = QPushButton('进行识别',self)
btn2.clicked.connect(self.do_catch)
运行结果如下,这样就基本实现了快速的读取大量文本数据
todo:我们已经获取了大量的文档,可以根据实际应用场景对文本数据进行进一步处理,如相对于文章来说,可以通过调用chatgpt来快速的获取大意以及关键词,对于账单可以利用正则表达式对需要的文本段进行筛选,然后输出想要的文件