在使用工业相机获取视频,或者其他设备获取视频时,为了保证效率,直接使用设备提供的sdk显示视频,能够最大限度地降低效率损失。减少了一些图像转换,数据传递的过程,但是这种情况也造成了另一个问题,第三方的显示窗口,我们无法直接进行修改。
通常情况下,我们会想到在视频上方叠加一个控件,在该控件上做一些简单的绘图操作,或添加一些透明按钮,以达到想要的目的。但是事实上并不是这么简单。
一般的,将widget或者label的句柄交出去,用其他的sdk直接显示一段视频(如相机自己的SDK),会出现遮挡状况。这种状况,即使将子控件属性设置为透明,也无法避免。
fig. 子控件遮挡视频
如上图所示,黄色的子控件设置为透明。他对为交出句柄的其他空间,并不存在遮挡,但是针对已经交出句柄的,该透明属性毫无作用。
为了解决该问题,现在提供一个解决方法。
以qlabel为例:我们计划在qlabel上显示视频,然后再另一个label上书写文字,并且改文字不能遮挡视频。
首先重写qlabel的绘图,并设置该label属性为:
setAttribute(Qt::WA_TranslucentBackground);
setWindowFlags(Qt::FramelessWindowHint | Qt::Tool);
以上步骤十分重要。
#include "myLabel.h"
#include"QPainter"
myLabel::myLabel(QWidget *parent)
: QLabel(parent)
{
setAttribute(Qt::WA_TranslucentBackground);
setWindowFlags(Qt::FramelessWindowHint | Qt::Tool);
show();
}
myLabel::~myLabel()
{
}
void myLabel::moveFunc(QPoint p)
{
move(p);
}
void myLabel::paintEvent(QPaintEvent* event)
{
QLabel::paintEvent(event);
QPainter painter(this);
painter.fillRect(this->rect(),QColor(255, 255, 0, 125));
}
在主界面中使用该label,但是发现该控件并不随主窗口一起移动,因此还要写一个重写主窗口的移动事件,让其每次移动之后发送自己的坐标,以便于子控件label更新位置。
void SDK::moveEvent(QMoveEvent* event)
{
QWidget::moveEvent(event);
double x = ui.widget->mapToGlobal(QPoint(0, 0)).x();
double y = ui.widget->mapToGlobal(QPoint(0, 0)).y();
QPoint coordinate(ui.widget->mapToGlobal(QPoint(0, 0)).x(), ui.widget->mapToGlobal(QPoint(0, 0)).y());
//cout << "发送坐标了" << endl;
emit sendPose(coordinate);
}
通过信号槽传递给该子控件,进行位置的更新即可
connect(this, &SDK::sendPose, ui.label_2,&myLabel::moveFunc);