文章目录
前言
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无法使用下,就自定义类去进行视图刷新,能够更加灵活,可以在视图上增加更多的操作