在工作中需要在实时视频上画矩形框,类似于深度学习里面的打标签。
根据别人的教程采用了Qt的事件过滤器采监控widget上鼠标事件和绘图事件但是画的矩形框并不显示。(实际上是因为本文后面阐述的那个问题,这种操作在Qlable显示的图像上画图是没问题的)
然后更改了策略,在widget上新建了一个透明widget
transparentWidget = new QWidget(ui->widget);
并设置其背景透明、设置其坐标与widget坐标相同,在transparentWidget上画矩形框。
但是又遇到了一个问题,画的矩形框中间部分不透明,一直显示背景颜色。将transparentWidget 放在其他界面上(如QLable显示的图片上)却没问题。猜测因该是因为将widget句柄交给海康的sdk用来显示实时视频的问题。于是更改了画矩形框的策略,我画了四条直线,这样就不会影响没画图的地方了。同事update()触发绘图事件的时候指定直线所在区域绘图。效果如下:
部分代码如下:
鼠标移动事件:
if(event->type() == QEvent::MouseMove)
{
transparentWidget->setGeometry(ui->widget->geometry());
QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent*>(event);
if (_dragging)
{
qDebug() << "in trans mouse move";
_endPoint = mouseEvent->pos();
float startx=_startPoint.x();
float starty=_startPoint.y();
float endx=_endPoint.x();
float endy=_endPoint.y();
float weight=qAbs(startx-endx)+6;
float height=qAbs(starty-endy)+6;
QRect r1(QPoint(startx-3, starty-3), QSize(weight, 6));
QRect r2(QPoint(startx-3, starty-3), QSize(6, height));
QRect r3(QPoint(startx-3, endy-3), QSize(weight, 6));
QRect r4(QPoint(endx-3, starty-3), QSize(6, height));
transparentWidget->repaint(r1);
transparentWidget->repaint(r2);
transparentWidget->repaint(r3);
transparentWidget->repaint(r4);
}
return true;
}
绘图事件处理:
void MainWindow::paintRec()
{
transparentWidget->setGeometry(ui->widget->geometry());
qDebug() << "transparentWidget:" << transparentWidget->size() << transparentWidget->geometry();
QPainter painterRec(transparentWidget);
painterRec.setCompositionMode(QPainter::CompositionMode_SourceOver);
painterRec.setPen(QPen(Qt::red, 5, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin));
float startx=_startPoint.x();
float starty=_startPoint.y();
float endx=_endPoint.x();
float endy=_endPoint.y();
painterRec.drawLine(startx,starty,endx,starty);
painterRec.drawLine(startx,starty,startx,endy);
painterRec.drawLine(endx,starty,endx,endy);
painterRec.drawLine(startx,endy,endx,endy);
}
算是采用了歪门邪道完成了任务,如果大家有更好的方法或者理解欢迎分享出来!