QVideoWidget遇到setAttribute(Qt::WA_TranslucentBackground)问题


前言

Qt下使用setAttribute(Qt::WA_TranslucentBackground)是因为自定义窗口,需要能够有圆角窗口,阴影特殊效果出现,但是如果出现这个窗口使用QVideoWidget基于该窗口指针父类显示视频效果时候,因该属性的设置导致QVideoWidget无法显示的问题出现。

无法显示

空了视频流不显示

关闭setAttribute(Qt::WA_TranslucentBackground)窗口无圆角

在这里插入图片描述

初始化QVideoFrame时候传nullptr父对象

在这里插入图片描述


一、QVideoWidget是什么?

QVideoWidget是Qt框架中的组件之一,它提供了一个用于显示视频的自定义窗口。您可以将QVideoWidget添加到应用程序的用户界面中,然后使用QMediaPlayer或其他支持Qt视频框架的组件将视频播放到该窗口中。

使用QVideoWidget,您可以轻松实现视频播放器的自定义UI,例如:显示视频标题和长度、调整播放音量、显示屏幕截图和元数据等。QVideoWidget还可以处理一些常见的视频操作,例如全屏模式、视频缩放和窗口大小更改

二、解决方法

最好使用QGraphicsView自行绘制视图内容

代码如下:

//头文件
#ifndef VIDEOVIEWFINDER_H
#define VIDEOVIEWFINDER_H

#include <QtWidgets/QGraphicsView>

class QGraphicsVideoItem;
class QVideoSink;

class VideoViewfinder : public QGraphicsView
{
    Q_OBJECT
public:
    explicit VideoViewfinder(QWidget *parent = nullptr);
    Q_INVOKABLE QVideoSink *videoSink() const;
    void setCutoutSize(const QSize &size);
    void setResolution(const QSize &size);
    void setVideoScale(qreal scale);
signals:
    void videoRatioChanged(const QSizeF &ratio);
protected:
    void resizeEvent(QResizeEvent *event) override;
private:
    void updateCutoutRect();
private:
    QSizeF m_resolution;
    QSizeF m_cutoutSize;
    qreal m_videoScale;
    QGraphicsScene *m_scene;
    QGraphicsVideoItem *m_videoItem;
    QGraphicsRectItem *m_cutoutMark;
};

#endif // VIDEOVIEWFINDER_H

#include "videoviewfinder.h"
#include <QtMultimediaWidgets/QGraphicsVideoItem>
#include <QtWidgets/QGraphicsScene>

VideoViewfinder::VideoViewfinder(QWidget *parent)
    : QGraphicsView(parent)
{
    m_videoScale = 1.0;

    setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff);
    setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff);

    m_videoItem = new QGraphicsVideoItem{nullptr};

    m_scene = new QGraphicsScene{this};
    m_scene->addItem(m_videoItem);

    setScene(m_scene);
}

void VideoViewfinder::setCutoutSize(const QSize &size)
{
    if (size.isEmpty())
    {
        if (m_cutoutMark != nullptr)
        {
            delete m_cutoutMark;
            m_cutoutMark = nullptr;
        }
    }
    else
    {
        if (m_cutoutMark == nullptr)
        {
            m_cutoutMark = new QGraphicsRectItem;
            m_cutoutMark->setPen(QPen{QColor{251, 86, 44}});
            m_cutoutMark->setBrush(QBrush{Qt::BrushStyle::NoBrush});
            m_scene->addItem(m_cutoutMark);
        }
    }
}

void VideoViewfinder::setResolution(const QSize &size)
{
    m_resolution = size;
}

void VideoViewfinder::setVideoScale(qreal scale)
{
    m_videoScale = scale;
}

QVideoSink *VideoViewfinder::videoSink() const
{
    return m_videoItem->videoSink();
}

void VideoViewfinder::resizeEvent(QResizeEvent *event)
{
    Q_UNUSED(event);

    const QSize &size = this->size();

    const QSizeF videoSize = QSizeF{size} * m_videoScale;
    m_videoItem->setPos(- videoSize.width() / 2.0, - videoSize.height() / 2.0);
    m_videoItem->setSize(videoSize);

    QSizeF ratio{videoSize.width() / (qreal)m_resolution.width(), videoSize.height() / (qreal)m_resolution.height()};
    emit videoRatioChanged(ratio);

    updateCutoutRect();
}

void VideoViewfinder::updateCutoutRect()
{
    if (m_resolution.isEmpty() || m_resolution.isNull())
        return;

    if (m_cutoutMark == nullptr)
        return;

    if (m_cutoutSize.isEmpty())
        return;

    const QSizeF &videoSize = m_videoItem->size();

    const QSizeF size = {m_cutoutSize.width() * videoSize.width() / m_resolution.width(),
                 m_cutoutSize.height() * videoSize.height() / m_resolution.height()};

    const QRectF rect = QRectF{QPointF{- size.width() / 2.0, - size.height() / 2.0}, size};
    m_cutoutMark->setRect(rect);
}


效果

能够显示流且能在视图上显示悬浮图标
在这里插入图片描述

总结

QVideoWidget无法使用下,就自定义类去进行视图刷新,能够更加灵活,可以在视图上增加更多的操作

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值