目录
前言
最近闲来无事研究了下pyqt5的框架,实现了基于tesseract识图,想在tesseract识图功能中添加个屏幕识图的功能类似于QQ截图,然后将截图自动识字,。
先不多说看看效果图:
主界面图:
截图界面图:
识图结果图:
实现
实现原理其实也挺简单的,借助于qt5的QWidget,重写控件的绘图方法,并且加上些鼠标按钮事件,下面写下主要功能的代码实现。
首先自写个窗口类继承于QWidget,设置窗口类标题栏去除,并且窗口透明显示。
class ScreenCaptureFrame(QWidget):
def __init__(self, parent, img: QImage = None):
super(ScreenCaptureFrame, self).__init__()
# 保存父窗口
self.parentWin = parent
# 设置窗口无标题栏
self.setWindowFlags(Qt.FramelessWindowHint)
# 设置窗口透明
self.setAttribute(Qt.WA_TranslucentBackground, True)
# 设置模态窗口
# self.setWindowModality(Qt.ApplicationModal)
然后,因为需要通过鼠标拖出矩形窗口,因此重载窗口鼠标事件,用于记录窗口按下事件与拖动事件,鼠标按下时记录鼠标按下点作为矩形区的开始点,拖动时记录结束点作为矩形结束点,并且刷新窗口重绘矩形区域。
鼠标按下重载:
def mousePressEvent(self, event: QMouseEvent):
"""
重写鼠标按下事件
:param event:
:return:
"""
try:
# 鼠标左键按下记录矩形开始点
if event.button() == Qt.LeftButton:
self.startPoint = event.pos()
self.isLeftPress = True
else:
self.isLeftPress = False
except Exception as e:
traceback.print_exc()
鼠标移动事件重载:
def mouseMoveEvent(self, event: QMouseEvent):
"""
重写鼠标移动事件
:param event:
:return:
"""
try:
# 鼠标左键按下记录矩形结束点
if hasattr(self, "isLeftPress") and self.isLeftPress:
self.endPoint = event.pos()
self.repaint()
except Exception as e:
traceback.print_exc()
鼠标松开事件重载:
def mouseReleaseEvent(self, event: QMouseEvent):
"""
重写鼠标松开事件
:param event:
:return:
"""
try:
# 鼠标左键按下记录矩形结束点
if event.button() == Qt.LeftButton:
self.endPoint = event.pos()
self.isLeftPress = False
self.repaint()
except Exception as e:
traceback.print_exc()
接下来最重要的重载绘图事件:
backPath作为窗口背景矩形区,fillPath作为鼠标拖动区域,通过QPainterPath的substracted方法,去除矩形区域填充半透明背景色。
def paintEvent(self, event: QPaintEvent):
"""
重写绘图事件
:param event:
:return:
"""
try:
backPath = QPainterPath()
backPath.addRect(0, 0, self.width(), self.height())
fillPath = QPainterPath()
if hasattr(self, "startPoint") and hasattr(self, "endPoint"):
movePath = QPainterPath()
movePath.addRect(QRectF(self.startPoint, self.endPoint))
fillPath = backPath.subtracted(movePath)
else:
fillPath = backPath
# 创建绘图设备
painter = QPainter(self)
# 绘制背景图
painter.drawImage(QPoint(0, 0), self.backImg)
painter.setPen(QPen(QColor(87, 170, 255), 5, Qt.SolidLine))
painter.drawPath(fillPath)
# 填充非选择区域
painter.fillPath(fillPath, QColor(0, 0, 0, 100))
except Exception as e:
traceback.print_exc()
截图完后,按键操作实现,空格键用于保存截图图片,enter键用于直接返回识图不保存,按键事件重写如下:
def keyReleaseEvent(self, event: QKeyEvent):
"""
重写按键事件
:param event:
:return:
"""
try:
# esc键关闭窗口
if event.key() == Qt.Key_Escape:
self.close()
# 父窗口恢复显示
self.parentWin.showNormal()
# enter键(数字键盘为Key_Enter)返回主窗口识图
elif event.key() == Qt.Key_Return or event.key() == Qt.Key_Enter:
if not (self.startPoint.x() == self.endPoint.x() and self.startPoint.y() == self.endPoint.y()):
image = self.backImg.copy(QRect(self.startPoint, self.endPoint))
self.close()
# 父窗口恢复显示
self.parentWin.showNormal()
self.parentWin.childWinCallBack(image)
# space键保存选择区域为图片
elif event.key() == Qt.Key_Space:
if not (self.startPoint.x() == self.endPoint.x() and self.startPoint.y() == self.endPoint.y()):
filePath, fileType = QFileDialog.getSaveFileName(self, "保存截图", "./",
"jpg图片 (*.jpg);;bmp图片(*.bmp);;png图片(*.png)")
if filePath.strip() != "":
image = self.backImg.copy(QRect(self.startPoint, self.endPoint))
image.save(filePath)
self.close()
# 父窗口恢复显示
self.parentWin.showNormal()
except Exception as e:
traceback.print_exc()
至此,屏幕截图窗口类实现完成,只需要再写个父窗口类调用此窗口类实现屏幕截图功能就可。
以上功能只是仿QQ截图功能代码,完整OCR代码看资源:
https://download.csdn.net/download/zwyact/11646209