使用PyQt的QLabel组件实现选定目标框功能的方法示例


Posted in Python onMay 19, 2020

问题背景

  基于PyQt5开发了一个可以用于目标跟踪的软件,在开发过程中遇到一个问题,就是如何在PyQt5的组件QLable中自主选定目标框,这个在opencv里面有专门的函数完成这个工作:cv2.selectROI(),我的目的就是在QLabel的基础上,实现类似函数cv2.selectROI()的功能,这样在运行程序的过程中,就能在视频框里面直接选取感兴趣区域。直接贴出实现的最终效果:

使用PyQt的QLabel组件实现选定目标框功能的方法示例

上图中的红色框框就是在QLabel的基础上实现的功能。

实现思路

  具体要实现的功能是,在视频显示区域,点击鼠标左键,开启选择,按照鼠标左键,移动游标,慢慢地绘制出红色的目标框。释放鼠标左键就停止选择目标框。最开始以为PyQt好歹也会提供这样的类来进行开发吧,后来发现其实是没有的,没办法只能写一个QLabel类的子类了。子类的命名为Label,继承自QLabel类,在子类中重写鼠标事件函数,接受鼠标在Label对象上位置信号。PyQt本来就有自己的事件循环,当鼠标落在视频显示区域的时候,触发到Label的鼠标事件,那么就可以开始绘制目标框了。

  这里要记录的就是鼠标按下左键时候的起始坐标pos_1和移动坐标pos_2pos_1=(x0,y0),pos_2=(x1,y1)

  重写按下鼠标事件 按下鼠标左键,触发事件函数mousePressEvent(),事件函数打开绘制标志位self.select_roi_flag,传入事件对象数据,初始化起始坐标x0,y0

  重写释放鼠标事件 按下鼠标左键,触发事件函数mousePressEvent(),关闭绘制标志位self.select_roi_flag

  绘制事件 继承鼠标事件绘制类,创建画笔类对象,在这可以设置画笔的颜色,画线的粗细,如果绘制标志位self.select_roi_flag是打开的,那么将事件对象的位置数据传给x1,y1QRect类是是PyQt的内置数据结构,具体结构是这样的Rect=(x,y,w,h),之后就调用画笔对象方法动态绘制目标框。直到绘制标志位被关闭,就是释放鼠标,则停止绘画。

具体实现代码:

from PyQt5.QtWidgets import QLabel
from PyQt5.QtCore import Qt,QRect
from PyQt5.QtGui import QPainter,QPen

class Label(QLabel):
  x0=0
  y0=0
  x1=0
  y1=0
  open_mouse_flag=False
  select_roi_flag=False
  draw_roi_flag=False
  clear_flag=False
  rect = QRect()

  #按下鼠标
  def mousePressEvent(self, event):
    if self.open_mouse_flag is True:
      self.select_roi_flag=True
      self.x0=event.x()
      self.y0=event.y()

  #释放鼠标
  def mouseReleaseEvent(self, event):
    self.select_roi_flag=False

  #移动鼠标
  def mouseMoveEvent(self, event):
    if self.select_roi_flag is True:
      self.x1=event.x()
      self.y1=event.y()
      if self.draw_roi_flag is True:
        self.update()

  #绘制事件
  def paintEvent(self,event):
    super().paintEvent(event)
    painter = QPainter(self)
    painter.setPen(QPen(Qt.red, 5, Qt.SolidLine))
    if self.clear_flag is True:
      self.x0=0
      self.y0=0
      self.x1=0
      self.y1=0
    self.rect = QRect(self.x0, self.y0, abs(self.x1 - self.x0), abs(self.y1 - self.y0))
    painter.drawRect(self.rect)
    self.update()

其他要注意的问题

  子类Label除了能自定义选择目标框,还要在更新内容是清除绘制内容,实现这个功能可以通过设置清空标志位clear_flag,当标志位打开的时候,将起始坐标和更新坐标重置为:(0,0)(0,0),这样绘制内容就被更新了。
具体实现代码:

# 清除label对象的绘制内容
def clear_label(self):
  self.label_show.clear_flag = True
  self.label_show.clear()

  此外我还重写了键盘事件,通过敲击键盘来控制鼠标的绘制事件,这里的内容主要包括切换游标,开启绘制事件,确认绘制事件。

具体实现代码:

# 重写键盘事件
def keyPressEvent(self, QKeyEvent):
  if self.open_keyboard_flag is True:         # 当键盘事件为真的是才有键盘事件监控
    if QKeyEvent.key() == Qt.Key_S:
      self.label_show.setCursor(Qt.CrossCursor)  # 切换游标为十字型
      self.label_show.open_mouse_flag = True
      self.label_show.draw_roi_flag = True
    if QKeyEvent.key() == Qt.Key_Q:         # 按下'q'键键盘监控关闭
      self.label_show.unsetCursor()
      self.label_show.draw_roi_flag = False
      self.label_show.open_mouse_flag = False
      self.open_keyboard_flag = False

到此这篇关于使用PyQt的QLabel组件实现选定目标框功能的方法示例的文章就介绍到这了,更多相关PyQt QLabel选定目标框 内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python切换hosts文件代码示例
Dec 31 Python
详解Python中的元组与逻辑运算符
Oct 13 Python
使用python3.5仿微软记事本notepad
Jun 15 Python
python解析基于xml格式的日志文件
Feb 25 Python
pandas.DataFrame.to_json按行转json的方法
Jun 05 Python
关于pycharm中pip版本10.0无法使用的解决办法
Oct 10 Python
flask框架自定义过滤器示例【markdown文件读取和展示功能】
Nov 08 Python
Python读取实时数据流示例
Dec 02 Python
完美解决keras 读取多个hdf5文件进行训练的问题
Jul 01 Python
Python设计密码强度校验程序
Jul 30 Python
python爬虫看看虎牙女主播中谁最“顶”步骤详解
Dec 01 Python
Python中time标准库的使用教程
Apr 13 Python
python 数据分析实现长宽格式的转换
May 18 #Python
如何把外网python虚拟环境迁移到内网
May 18 #Python
python 实现 hive中类似 lateral view explode的功能示例
May 18 #Python
pandas dataframe 中的explode函数用法详解
May 18 #Python
Python pandas 列转行操作详解(类似hive中explode方法)
May 18 #Python
Win 10下Anaconda虚拟环境的教程
May 18 #Python
python异常处理之try finally不报错的原因
May 18 #Python
You might like
自己做矿石收音机
2021/03/02 无线电
PHP array_multisort() 函数的深入解析
2013/06/20 PHP
解析php函数method_exists()与is_callable()的区别
2013/06/21 PHP
laravel学习笔记之模型事件的几种用法示例
2017/08/15 PHP
支持汉转拼和拼音分词的PHP中文工具类ChineseUtil
2018/02/23 PHP
PHP ADODB生成下拉列表框功能示例
2018/05/29 PHP
获取DOM对象的几种扩展及简写
2006/10/09 Javascript
jQuery为iframe的body添加click事件的实现代码
2011/04/07 Javascript
JQuery中form验证出错信息的查看方法
2013/10/08 Javascript
JS获取随机数函数可自定义最小值最大值
2014/05/08 Javascript
事件委托与阻止冒泡阻止其父元素事件触发
2014/09/02 Javascript
js实现对table动态添加、删除和更新的方法
2015/02/10 Javascript
PHP结合jQuery实现红蓝投票功能特效
2015/07/22 Javascript
JavaScript常用字符串与数组扩展函数小结
2016/04/24 Javascript
JS点击某个图标或按钮弹出文件选择框的实现代码
2016/09/27 Javascript
Ionic 2 实现列表滑动删除按钮的方法
2017/01/22 Javascript
基于JavaScript中字符串的match与replace方法(详解)
2017/12/04 Javascript
vuex2中使用mapGetters/mapActions报错的解决方法
2018/10/20 Javascript
js实现弹出框的拖拽效果实例代码详解
2019/04/16 Javascript
Python SQLite3简介
2018/02/22 Python
Python3.6实现根据电影名称(支持电视剧名称),获取下载链接的方法
2019/08/26 Python
使用 Supervisor 监控 Python3 进程方式
2019/12/05 Python
Python安装依赖(包)模块方法详解
2020/02/14 Python
jenkins+python自动化测试持续集成教程
2020/05/12 Python
matplotlib 生成的图像中无法显示中文字符的解决方法
2020/06/10 Python
Css3+Js制作漂亮时钟(附源码)
2013/04/24 HTML / CSS
美国高端医师级美容产品电商:BeautifiedYou.com
2017/04/17 全球购物
德国、奥地利和瑞士最大的旅行和度假门户网站:HolidayCheck
2019/11/14 全球购物
师德师风建设方案
2014/05/08 职场文书
安全承诺书格式
2014/05/21 职场文书
教师学习三严三实心得体会
2014/10/13 职场文书
2014年办公室个人工作总结
2014/11/12 职场文书
工作失误检讨书范文
2015/01/26 职场文书
幼儿园秋季开学通知
2015/07/16 职场文书
2016五一手机促销广告语
2016/01/28 职场文书
Go 自定义package包设置与导入操作
2021/05/06 Golang