Source code
Revision control
Copy as Markdown
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qvideowidget.h"
#include "qvideowidget_p.h"
#include <QtMultimedia/private/qtmultimediaglobal_p.h>
#include <QtMultimedia/qtmultimediaglobal.h>
#include <QtMultimedia/qvideoframeformat.h>
#include <QtMultimedia/qvideosink.h>
#include <QtMultimedia/private/qvideowindow_p.h>
#include <QtGui/qevent.h>
#include <QtGui/qguiapplication.h>
#include <QtCore/qobject.h>
QT_BEGIN_NAMESPACE
using namespace Qt::Literals;
/*!
\class QVideoWidget
\brief The QVideoWidget class provides a widget which presents video
produced by a media object.
\ingroup multimedia
\ingroup multimedia_video
\inmodule QtMultimediaWidgets
Attaching a QVideoWidget to a QMediaPlayer or QCamera allows it to display the
video or image output of that object.
\snippet multimedia-snippets/video.cpp Video widget
\b {Note}: Only a single display output can be attached to a media
object at one time.
\warning QVideoWidget is not supported on the \c eglfs platform plugin.
\sa QCamera, QMediaPlayer, QGraphicsVideoItem
*/
/*!
\variable QVideoWidget::d_ptr
\internal
*/
/*!
Constructs a new video widget.
The \a parent is passed to QWidget.
*/
QVideoWidget::QVideoWidget(QWidget *parent)
: QWidget(parent, {})
, d_ptr(new QVideoWidgetPrivate)
{
d_ptr->q_ptr = this;
d_ptr->isEglfs = QGuiApplication::platformName().startsWith("eglfs"_L1, Qt::CaseInsensitive);
if (d_ptr->isEglfs) {
qWarning("QVideoWidget is not supported on eglfs");
d_ptr->fakeVideoSink = new QVideoSink(this);
} else {
d_ptr->videoWindow = new QVideoWindow;
d_ptr->videoWindow->setFlag(Qt::WindowTransparentForInput, true);
d_ptr->windowContainer = QWidget::createWindowContainer(d_ptr->videoWindow, this, Qt::WindowTransparentForInput);
d_ptr->windowContainer->move(0, 0);
d_ptr->windowContainer->resize(size());
connect(d_ptr->videoWindow, &QVideoWindow::aspectRatioModeChanged, this,
&QVideoWidget::aspectRatioModeChanged);
}
}
/*!
Destroys a video widget.
*/
QVideoWidget::~QVideoWidget()
{
delete d_ptr->videoWindow;
delete d_ptr;
}
/*!
Returns the QVideoSink instance.
*/
QVideoSink *QVideoWidget::videoSink() const
{
return d_ptr->videoWindow ? d_ptr->videoWindow->videoSink() : d_ptr->fakeVideoSink;
}
/*!
\property QVideoWidget::aspectRatioMode
\brief how video is scaled with respect to its aspect ratio.
*/
Qt::AspectRatioMode QVideoWidget::aspectRatioMode() const
{
return d_ptr->videoWindow ? d_ptr->videoWindow->aspectRatioMode() : Qt::KeepAspectRatio;
}
void QVideoWidget::setAspectRatioMode(Qt::AspectRatioMode mode)
{
if (d_ptr->videoWindow)
d_ptr->videoWindow->setAspectRatioMode(mode);
}
/*!
\property QVideoWidget::fullScreen
\brief whether video display is confined to a window or is fullScreen.
*/
void QVideoWidget::setFullScreen(bool fullScreen)
{
Q_D(QVideoWidget);
if (isFullScreen() == fullScreen)
return;
if (d_ptr->isEglfs)
return;
Qt::WindowFlags flags = windowFlags();
if (fullScreen) {
// get the position of the widget in global coordinates
QPoint position = mapToGlobal(QPoint(0,0));
d->nonFullScreenFlags = flags & (Qt::Window | Qt::SubWindow);
d_ptr->nonFullscreenPos = pos();
flags |= Qt::Window;
flags &= ~Qt::SubWindow;
setWindowFlags(flags);
// move the widget to the position it had on screen, so that showFullScreen() will
// place it on the correct screen
move(position);
showFullScreen();
} else {
flags &= ~(Qt::Window | Qt::SubWindow); //clear the flags...
flags |= d->nonFullScreenFlags; //then we reset the flags (window and subwindow)
setWindowFlags(flags);
showNormal();
move(d_ptr->nonFullscreenPos);
d_ptr->nonFullscreenPos = {};
}
}
/*!
Returns the size hint for the current back end,
if there is one, or else the size hint from QWidget.
*/
QSize QVideoWidget::sizeHint() const
{
auto size = videoSink()->videoSize();
if (size.isValid())
return size;
return QWidget::sizeHint();
}
/*!
\reimp
Current event \a event.
Returns the value of the base class QWidget::event(QEvent *event) function.
*/
bool QVideoWidget::event(QEvent *event)
{
Q_D(QVideoWidget);
if (event->type() == QEvent::WindowStateChange) {
bool fullScreen = bool(windowState() & Qt::WindowFullScreen);
if (fullScreen != d->wasFullScreen) {
Q_EMIT fullScreenChanged(fullScreen);
d->wasFullScreen = fullScreen;
}
}
return QWidget::event(event);
}
/*!
\reimp
Handles the show \a event.
*/
void QVideoWidget::showEvent(QShowEvent *event)
{
QWidget::showEvent(event);
}
/*!
\reimp
Handles the hide \a event.
*/
void QVideoWidget::hideEvent(QHideEvent *event)
{
QWidget::hideEvent(event);
}
/*!
\reimp
Handles the resize \a event.
*/
void QVideoWidget::resizeEvent(QResizeEvent *event)
{
if (!d_ptr->isEglfs)
d_ptr->windowContainer->resize(event->size());
QWidget::resizeEvent(event);
}
/*!
\reimp
Handles the move \a event.
*/
void QVideoWidget::moveEvent(QMoveEvent *event)
{
if (!d_ptr->isEglfs)
QWidget::moveEvent(event);
}
QT_END_NAMESPACE
#include "moc_qvideowidget.cpp"