使用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函数式编程指南(四):生成器详解
Jun 24 Python
Python实现数通设备端口使用情况监控实例
Jul 15 Python
python操作字典类型的常用方法(推荐)
May 16 Python
Python实现两款计算器功能示例
Dec 19 Python
python实现守护进程、守护线程、守护非守护并行
May 05 Python
使用python将大量数据导出到Excel中的小技巧分享
Jun 14 Python
Linux 修改Python命令的方法示例
Dec 03 Python
Django项目中实现使用qq第三方登录功能
Aug 13 Python
python 上下文管理器及自定义原理解析
Nov 19 Python
python+selenium+Chrome options参数的使用
Mar 18 Python
教你怎么用python selenium实现自动化测试
May 27 Python
python 爬取京东指定商品评论并进行情感分析
May 27 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
PHP中通过ADO调用Access数据库的方法测试不通过
2006/12/31 PHP
用php随机生成福彩双色球号码的2种方法
2013/02/04 PHP
ThinkPHP中where()使用方法详解
2016/04/19 PHP
CI框架整合smarty步骤详解
2016/05/19 PHP
thinkphp多表查询两表有重复相同字段的完美解决方法
2016/09/22 PHP
PHP实现模拟http请求的方法分析
2017/12/20 PHP
火狐浏览器(firefox)下获得Event对象以及keyCode
2008/11/13 Javascript
jquery判断字符输入个数(数字英文长度记为1,中文记为2,超过长度自动截取)
2010/10/15 Javascript
jQuery学习总结之元素的相对定位和选择器(持续更新)
2011/04/26 Javascript
js操作iframe的一些方法介绍
2013/06/25 Javascript
js动态修改input输入框的type属性(实现方法解析)
2013/11/13 Javascript
js 设置缓存及获取设置的缓存
2014/05/08 Javascript
XML文件转化成NSData对象的方法
2015/08/12 Javascript
js日期插件dateHelp获取本月、三个月、今年的日期
2016/03/07 Javascript
Angular.js与Bootstrap相结合实现手风琴菜单代码
2016/04/13 Javascript
jquery遍历table的tr获取td的值实现方法
2016/05/19 Javascript
jQuery实现表格文本框淡入更改值后淡出效果
2016/09/27 Javascript
Nodejs多站点切换Htpps协议详解及简单实例
2017/02/23 NodeJs
jQuery插件开发发送短信倒计时功能代码
2017/05/09 jQuery
spring+angular实现导出excel的实现代码
2019/02/27 Javascript
原生JS实现烟花效果
2020/03/10 Javascript
vue实现tab栏点击高亮效果
2020/08/19 Javascript
H5 js点击按钮复制文本到粘贴板
2020/11/19 Javascript
vue实现验证用户名是否可用
2021/01/20 Vue.js
[06:07]辉夜杯现场观众互动 “比谁远送显示器”
2015/12/26 DOTA
在Django框架中编写Contact表单的教程
2015/07/17 Python
Python实现可设置持续运行时间、线程数及时间间隔的多线程异步post请求功能
2018/01/11 Python
使用python实现unix2dos和dos2unix命令的例子
2019/08/13 Python
详解python路径拼接os.path.join()函数的用法
2019/10/09 Python
详解python tkinter模块安装过程
2020/01/06 Python
MxNet预训练模型到Pytorch模型的转换方式
2020/05/25 Python
部署Django到阿里云服务器教程示例
2020/06/03 Python
New Balance澳大利亚官网:运动鞋和健身服装
2019/02/23 全球购物
Monki官网:斯堪的纳维亚的独立时尚品牌
2020/11/09 全球购物
SIMON MILLER官网:洛杉矶的生活方式品牌
2020/10/19 全球购物
国际贸易专业个人鉴定
2014/02/22 职场文书