使用PyQt的QLabel组件实现选定目标框功能的方法示例
作者:lonly_girl 发布时间:2022-01-08 22:43:21
问题背景
基于PyQt5
开发了一个可以用于目标跟踪的软件,在开发过程中遇到一个问题,就是如何在PyQt5
的组件QLable
中自主选定目标框,这个在opencv
里面有专门的函数完成这个工作:cv2.selectROI()
,我的目的就是在QLabel
的基础上,实现类似函数cv2.selectROI()
的功能,这样在运行程序的过程中,就能在视频框里面直接选取感兴趣区域。直接贴出实现的最终效果:
上图中的红色框框就是在QLabel
的基础上实现的功能。
实现思路
具体要实现的功能是,在视频显示区域,点击鼠标左键,开启选择,按照鼠标左键,移动游标,慢慢地绘制出红色的目标框。释放鼠标左键就停止选择目标框。最开始以为PyQt
好歹也会提供这样的类来进行开发吧,后来发现其实是没有的,没办法只能写一个QLabel
类的子类了。子类的命名为Label
,继承自QLabel
类,在子类中重写鼠标事件函数,接受鼠标在Label
对象上位置信号。PyQt
本来就有自己的事件循环,当鼠标落在视频显示区域的时候,触发到Label
的鼠标事件,那么就可以开始绘制目标框了。
这里要记录的就是鼠标按下左键时候的起始坐标pos_1
和移动坐标pos_2
,pos_1=(x0,y0)
,pos_2=(x1,y1)
。
重写按下鼠标事件 按下鼠标左键,触发事件函数mousePressEvent()
,事件函数打开绘制标志位self.select_roi_flag
,传入事件对象数据,初始化起始坐标x0,y0
。
重写释放鼠标事件 按下鼠标左键,触发事件函数mousePressEvent()
,关闭绘制标志位self.select_roi_flag
。
绘制事件 继承鼠标事件绘制类,创建画笔类对象,在这可以设置画笔的颜色,画线的粗细,如果绘制标志位self.select_roi_flag
是打开的,那么将事件对象的位置数据传给x1,y1
。QRect
类是是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
来源:https://blog.csdn.net/lonly_girl/article/details/106205622


猜你喜欢
- 在ASP.NET中,如何连接 SQLServer数据库?连接数据库:<%@ Import Namespace=&q
- 本文实例讲述了Bootstrap实现前端登录页面带验证码功能。分享给大家供大家参考,具体如下:Bootstrap有自定义的验证码样式,在前端
- 一.虚拟机端1.找到mysql的配置文件:sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf按"
- 1-错误详情cmd下运行net start mysql启动MySQL服务:提示发生系统错误5。拒绝访问。cmd管理员模式运行可以启动MySQ
- java连接Access数据库的方法,分享给大家步骤:1.现在我们一般使用的编译环境是java SE 1.8,不支持odbc的连接方式,所以
- 代码: import os while True: dynamic = input('输入计算表达式:') if dynam
- 介绍shutil 名字来源于 shell utilities,有学习或了解过Linux的人应该都对 shell 不陌生,可以借此来记忆模块的
- 最近遇到一个现象,将做好的软件放在更高分辨率的电脑上运行,会导致字体显示不完全,出现被控件遮挡的情况。具体原因可以上网查询,在这里将记录下解
- 一、背景介绍今天,野鸡大学高(三)班的月考成绩出来了,这里先给大家公布一下各位同学的考试成绩。接着,在给大家公布一下各位同学的生活消费情况。
- 前言RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统。他遵循Mozilla Public License开源协议。MQ全称
- 目录安装基本操作打开图像转换格式展示图片剪裁合并缩略图旋转滤镜二次创作画线文字总结文 | 豆豆来源:Python 技术「ID: python
- 移动端适配满足多个查询时的优先级: 请注意,可以同时满足多个查询,并且它们都将由mergeOption合并,mergeOption稍后由me
- Todo清单需要实现的功能有添加任务、删除任务、编辑任务,操作要关联数据库。任务需要绑定用户,部门。用户需要绑定部门。{#自己编写一个基类模
- Django默认支持Session,并且默认是将Session数据存储在数据库中的修改session存取放在数据库中SESSION_ENGI
- vue中,我们构建单页面应用时候,一定必不可少用到vue-routervue-router 就是我们的路由,这个由vue官方提供的插件首先在
- Python写倒序输出(任意位数)倒序输出数字这种方法最后输出的是字符而不是数字x=int(input('请输入任意一个数字:
- 前言文件和目录操作是很常见的功能,这里做个简单的总结,包括注意事项和实际的实现代码,基本日常开发都够用了目录操作判断目录或是文件是否存在os
- 目录1、SKlearn 是什么2、SKlearn 的安装3、SKlearn 内置数据集测试问题数据集实际问题数据集4、Sklearn 数模笔
- 之前在Ubuntu 16.04安装 MySQL的时候很顺利,这次在 Ubuntu 18.04 中安装 MySQL 5.7.23 中,遇到一些
- 本文用python实现线性回归算法,供大家参考,具体内容如下# -*- coding: utf-8 -*-"""