Qt QWidget视频上叠加文字

需求:在调用其它音视频SDK的时候,在windows上一般会传入一个 winId 控件来显示视频,这个winID在Qt中一般是QWidget。目前想在这个视频上 显示一些提示信息,比如视频源的名字。 

一,曾尝试过的几种方案

在视频源上写入:

(1),利用opencv ,将原始yuv数据 转成mat,然后利用opencv的内置函数,绘制文字。不过这样的缺点是,引入了第三方库并且耗费大量cpu资源。

(2),利用opengl 在渲染yuv数据时,绘制文字。经测试,利用openg进行渲染,可直接利用QWidget cpu利用率一样,可能是自己写错了,所以此方案也放弃。

在显示端写入:

(1),利用qml控件,叠加item窗体。qml本身也用了opengl渲染,效果和上述方案2一样,opengl 玩不明白。

(2),利用QWidget 控件叠加,至于上层,背景透明。简单方便 缺点是如果利用采集卡复制视频流,然后利用第三方软件播放,则名字就看不见了,因为数据源本身不含有名字信息。

 

二,代码

#ifndef VWIDGET_H
#define VWIDGET_H
#include <QWidget>
#include <QPainter>
class QLabel;

class NameWidget:public QWidget{
     Q_OBJECT
public:
    NameWidget(QWidget*parent =nullptr);

    void setName(const QString &name);

protected:
    void paintEvent(QPaintEvent *);

private:
    QColor m_color;
    QLabel *m_label;

};

class VideoWidget : public QWidget
{
    Q_OBJECT
public:
    VideoWidget(QWidget*paren=nullptr);
    virtual ~VideoWidget() {}

    QWidget* video(){return m_videoWidget;}
    void setMicCameraStatus(bool _mic,bool _cam);
    void setName(const QString &name);

    void setIsMaster(bool isMaster);
    void setShowNameLabel(bool show);


private:
    QLabel* m_mediaStatsLabel;//麦克风和 摄像机状态
    QWidget* m_videoWidget;
    NameWidget *m_nameWidget;
    bool m_isMaster;
    bool m_isShowName;
protected:
    void resizeEvent(QResizeEvent *);

};

#endif // VWIDGET_H

 

#include "videowidget.h"
#include <QLabel>
#include <QGridLayout>
#include <qDebug>
NameWidget::NameWidget(QWidget *parent):QWidget (parent)
{
    m_color = QColor(100,100,100,100);
    m_label = new QLabel(this);
    QFont ft;
    ft.setPointSize(35);
    m_label->setFont(ft);
    QString styleSheet = QString::fromUtf8("color: rgb(255, 255, 255);");
    m_label->setStyleSheet(styleSheet);

    m_label->setText(QString::fromUtf8("显示自己"));
    QGridLayout *layout = new QGridLayout(this);
    layout->setContentsMargins(9,0,0,0);
    layout->addWidget(m_label);
    this->setLayout(layout);
}

void NameWidget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.fillRect(this->rect(),m_color);
}

void NameWidget::setName(const QString &name)
{
    m_label->setText(name);
}


VideoWidget::VideoWidget(QWidget*paren):QWidget (paren),
    m_isMaster(false),m_isShowName(false){

    m_mediaStatsLabel = new QLabel(this);
    this->setAttribute(Qt::WA_TranslucentBackground);
    QString styleSheet = QString::fromUtf8("color: rgb(255, 255, 255);\n"
                                           "background-color: rgb(0, 0, 0,100);");
    m_mediaStatsLabel->setStyleSheet(styleSheet);
    QFont ft;
    ft.setPointSize(10);
    m_mediaStatsLabel->setFont(ft);
    m_mediaStatsLabel->raise();
    setMicCameraStatus(true,true);
    m_mediaStatsLabel->hide();

    m_videoWidget = new QWidget(this);
    QGridLayout* layout = new QGridLayout(this);
    layout->setContentsMargins(0,0,0,0);
    layout->addWidget(m_videoWidget);
    this->setLayout(layout);
    m_videoWidget->lower();

    //
    m_nameWidget = new NameWidget(this);
    m_nameWidget->setWindowFlags(Qt::FramelessWindowHint|Qt::Dialog|Qt::WindowStaysOnTopHint|Qt::SubWindow);
    m_nameWidget->setAttribute(Qt::WA_TranslucentBackground, true);
    QPalette pal;
    pal.setColor(QPalette::Background,QColor(90,90,90,90));
    m_nameWidget->setAutoFillBackground(true);
    m_nameWidget->setPalette(pal);
    m_nameWidget->hide();

    setAttribute(Qt::WA_TransparentForMouseEvents, true);
}

void VideoWidget::setMicCameraStatus(bool _mic, bool _cam)
{
    QString mic;
    QString cam;
    if(_mic)
        mic="  Mic:ON";
    else {
        mic="  Mic:OFF";
    }

    if(_cam)
        cam=" Cam:ON";
    else {
        cam=" Cam:OFF";
    }
    m_mediaStatsLabel->setText(cam+mic);
}

void VideoWidget::setName(const QString &name)
{
    m_nameWidget->setName(name);
}

void VideoWidget::setIsMaster(bool isMaster)
{
    m_isMaster = isMaster;
}

void VideoWidget::setShowNameLabel(bool show)
{
    m_isShowName=show;
}

void VideoWidget::resizeEvent(QResizeEvent *e)
{
    if(!m_isMaster)
        m_mediaStatsLabel->show();

    if(m_isShowName)
        m_nameWidget->show();
    else {
        m_nameWidget->hide();
    }

    m_mediaStatsLabel->setGeometry(this->width()-120,0,120,15);//状态信息
    m_nameWidget->setGeometry(this->x(),this->y()+this->height()-53,this->width()/3,50);
    return QWidget::resizeEvent(e);
}

关键代码:

setWindowFlags(Qt::FramelessWindowHint|Qt::Dialog|Qt::WindowStaysOnTopHint|Qt::SubWindow);
    m_nameWidget->setAttribute(Qt::WA_TranslucentBackground, true);
    QPalette pal;
    pal.setColor(QPalette::Background,QColor(90,90,90,90));
    m_nameWidget->setAutoFillBackground(true);
    m_nameWidget->setPalette(pal);
    m_nameWidget->hide();

    setAttribute(Qt::WA_TransparentForMouseEvents, true);

三,效果

  • 1
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
Qt中,可以使用QWidget来创建视频窗口,并且可以在视频窗口上叠加控件。 首先,我们需要使用QVideoWidget来创建视频窗口,这个类继承自QWidget并且专门用于显示视频。我们可以将其放置在主窗口中的合适位置,并设置其大小和位置。 接下来,我们可以通过使用QMediaPlayer和QMediaPlaylist来加载和播放视频。首先,我们需要创建一个QMediaPlayer对象,并将其与QVideoWidget对象关联起来,这样视频就可以在视频窗口中显示出来。然后,我们可以使用QMediaPlaylist来加载视频文件,并将其添加到播放列表中。最后,我们通过调用QMediaPlayer的play()函数来开始播放视频叠加控件的方法是,我们可以创建其他的QWidget控件,如QPushButton、QLabel等,然后将其放置在视频窗口上,并设置其位置和大小。可以使用QWidget的setGeometry()函数来设置控件的位置和大小。另外,我们可以使用QWidget的setStyleSheet()函数来设置控件的样式。 需要注意的是,控件的大小和位置应该相对于视频窗口来设置,这样才能正确地叠加视频窗口上。另外,如果视频窗口被最大化或调整大小,叠加的控件也应该跟随调整大小,并且相对于视频窗口进行适当的缩放和调整。 总结起来,要实现叠加控件在Qt视频窗口上,我们可以使用QVideoWidget创建视频窗口,使用QMediaPlayer和QMediaPlaylist加载和播放视频,然后创建其他QWidget控件并将其叠加视频窗口上。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

土拨鼠不是老鼠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值