WebEngine ウィジェット ビデオプレーヤーの例

QWebEngineView を使用してフルスクリーン動画を表示します。

Video Playerは、QWebEngineView を使用して HTML5 動画のフルスクリーン再生をサポートする方法を示します。

Fullscreen APIは、Web ページがその HTML 要素の 1 つをユーザーの画面全体を占めるように要求できるようにする、クロス ブラウザ Javascript API です。一般的には、<video> 要素を使用したフルスクリーン・ビデオの再生に使用されますが、原理的には、あらゆる HTML コンテンツをフルスクリーン・モードで表示するために使用できます。Qt WebEngine はこの API をサポートしていますが、デフォルトでは無効になっています。この例では、この API を有効にするために必要な手順を示します:

  • QWebEngineSettings で有効にします。
  • 新しいフルスクリーンウィンドウを作成してQWebEnginePage::fullScreenRequested シグナルを処理する。
  • 通知ポップアップを表示して、フルスクリーンで表示されていることをユーザーに知らせる。

例の実行

Qt Creator からサンプルを実行するには、Welcome モードを開き、Examples からサンプルを選択します。詳細については、Building and Running an Example を参照してください。

概要

起動すると、サンプル・プログラムは、埋め込まれた YouTube ビデオ・プレーヤーを表示するQWebEngineView を持つ通常の(フルスクリーンではない)ウィンドウを作成します。フルスクリーン・トグル・ボタン(右下隅)をクリックすると、フルスクリーン・モードになります。また、エスケープキーを押すことでフルスクリーンモードを終了できることを知らせる通知オーバーレイが中央に表示されるはずです。

実装的には、フルスクリーンモードに入るには、別のQWebEngineView インスタンスで新しいフルスクリーンウィンドウを作成し、通常のウィンドウのQWebEngineView からこの新しいQWebEngineViewQWebEnginePage を移行する必要があります。フルスクリーンモードを終了すると、この移行は逆になる。

サンプル・コードは3つのクラス、MainWindowFullScreenWindowFullScreenNotification に分かれています。クラスMainWindowFullScreenWindow はそれぞれ1つのトップレベル・ウィンドウの管理を担当し、FullScreenNotification は通知ボックスのスタイリングとアニメーションを担当します。MainWindow は起動時に作成され、プログラム実行中ずっと存在します。一方、FullScreenWindow はフルスクリーンモードになるたびに作成されます。

MainWindow クラスの宣言

MainWindow は、QWebEngineView を中心ウィジェットとして持つQMainWindow です:

#include "fullscreenwindow.h"

#include <QMainWindow>
#include <QWebEngineView>
#include <QWebEngineFullScreenRequest>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);

private slots:
    void fullScreenRequested(QWebEngineFullScreenRequest request);

private:
    QWebEngineView *m_view;
    QScopedPointer<FullScreenWindow> m_fullScreenWindow;
};

MainWindowクラスの定義

コンストラクタでは、まずQWebEngineView を中心ウィジェットとして設定します:

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , m_view(new QWebEngineView(this))
{
    setCentralWidget(m_view);

次に、Qt WebEngine がフルスクリーン API のサポートをアドバタイズするように設定します:

    m_view->settings()->setAttribute(QWebEngineSettings::FullScreenSupportEnabled, true);

この行がないと、ページ上で動作している Javascript がブラウザがフルスクリーンモードをサポートしていないことを検出できるため、フルスクリーン切り替えボタンは無効(グレー表示)になります。

次に、fullScreenRequested シグナルをスロットに接続します:

    connect(m_view->page(),
            &QWebEnginePage::fullScreenRequested,
            this,
            &MainWindow::fullScreenRequested);

このシグナルは、ページ上のJavascriptがフルスクリーンモードに入りたいとき、またはフルスクリーンモードから抜けたいときに、いつでも発せられます。このシグナルを処理しない場合(ただし、FullScreenSupportEnabled 属性はtrue のまま)、トグルボタンは有効になりますが、Javascriptのフルスクリーンリクエストが拒否されるため、クリックしても効果はありません。

最後に、いくつかのHTML(サンプルに含まれるwebenginewidgets/videoplayer/data/index.html を参照)をQWebEngineView に読み込みます:

    m_view->load(QUrl(QStringLiteral("qrc:/index.html")));

MainWindow の2番目の部分は、フルスクリーン・リクエストの処理です:

void MainWindow::fullScreenRequested(QWebEngineFullScreenRequest request)
{
    if (request.toggleOn()) {
        if (m_fullScreenWindow)
            return;
        request.accept();
        m_fullScreenWindow.reset(new FullScreenWindow(m_view));
    } else {
        if (!m_fullScreenWindow)
            return;
        request.accept();
        m_fullScreenWindow.reset();
    }
}

フルスクリーンモードに入るときに新しいFullScreenWindow

FullScreenWindowクラスの宣言

FullScreenWindow は、QWebEngineViewFullScreenNotification を含むQWidget です。

#include <QWidget>

QT_BEGIN_NAMESPACE
class QWebEngineView;
QT_END_NAMESPACE

class FullScreenNotification;

class FullScreenWindow : public QWidget
{
    Q_OBJECT
public:
    explicit FullScreenWindow(QWebEngineView *oldView, QWidget *parent = nullptr);
    ~FullScreenWindow();

protected:
    void resizeEvent(QResizeEvent *event) override;

private:
    QWebEngineView *m_view;
    FullScreenNotification *m_notification;
    QWebEngineView *m_oldView;
    QRect m_oldGeometry;
};

FullScreenWindow クラスの定義

コンストラクタは、通常のウィンドウを非表示にし(ジオメトリは保存する)、代わりに新しいFullScreenWindow を表示します:

FullScreenWindow::FullScreenWindow(QWebEngineView *oldView, QWidget *parent)
    : QWidget(parent)
    , m_view(new QWebEngineView(this))
    , m_notification(new FullScreenNotification(this))
    , m_oldView(oldView)
    , m_oldGeometry(oldView->window()->geometry())
{
    m_view->stackUnder(m_notification);

    auto exitAction = new QAction(this);
    exitAction->setShortcut(Qt::Key_Escape);
    connect(exitAction, &QAction::triggered, [this]() {
        m_view->triggerPageAction(QWebEnginePage::ExitFullScreen);
    });
    addAction(exitAction);

    m_view->setPage(m_oldView->page());
    setGeometry(m_oldGeometry);
    showFullScreen();
    m_oldView->window()->hide();
}

QWebEngineView::setPage を呼び出すと、ウェブ・ページがMainWindow のビューからFullScreenWindow のビューに移動します。

デストラクタでは、同じメソッドを使ってページを戻し、メイン・ウィンドウのジオメトリと可視性を元に戻します:

FullScreenWindow::~FullScreenWindow()
{
    m_oldView->setPage(m_view->page());
    m_oldView->window()->setGeometry(m_oldGeometry);
    m_oldView->window()->show();
    hide();
}

QWidget::resizeEvent をオーバーライドして手動レイアウトを行い、QWebEngineView を最大化し、FullScreenNotification をウィンドウの中央に配置します:

void FullScreenWindow::resizeEvent(QResizeEvent *event)
{
    QRect viewGeometry(QPoint(0, 0), size());
    m_view->setGeometry(viewGeometry);

    QRect notificationGeometry(QPoint(0, 0), m_notification->sizeHint());
    notificationGeometry.moveCenter(viewGeometry.center());
    m_notification->setGeometry(notificationGeometry);

    QWidget::resizeEvent(event);
}

FullScreenNotificationクラスの宣言

FullScreenNotification は、QLabel にスタイリングとアニメーションを加えただけのものです:

#include <QLabel>

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

protected:
    void showEvent(QShowEvent *event) override;

signals:
    void shown();

private:
    bool m_previouslyVisible;
};

FullScreenWindowクラスの定義

コンストラクタでは、QLabel を設定し、Animation Framework を使用して遅延フェードアウト・アニメーションを設定します:

FullScreenNotification::FullScreenNotification(QWidget *parent)
    : QLabel(parent)
    , m_previouslyVisible(false)
{
    setText(tr("You are now in full screen mode. Press ESC to quit!"));
    setStyleSheet(
        "font-size: 24px;"
        "color: white;"
        "background-color: black;"
        "border-color: white;"
        "border-width: 2px;"
        "border-style: solid;"
        "padding: 100px");
    setAttribute(Qt::WA_TransparentForMouseEvents);

    auto effect = new QGraphicsOpacityEffect;
    effect->setOpacity(1);
    setGraphicsEffect(effect);

    auto animations = new QSequentialAnimationGroup(this);
    animations->addPause(3000);
    auto opacityAnimation = new QPropertyAnimation(effect, "opacity", animations);
    opacityAnimation->setDuration(2000);
    opacityAnimation->setStartValue(1.0);
    opacityAnimation->setEndValue(0.0);
    opacityAnimation->setEasingCurve(QEasingCurve::OutQuad);
    animations->addAnimation(opacityAnimation);

    connect(this, &FullScreenNotification::shown,
            [animations](){ animations->start(); });

    connect(animations, &QAbstractAnimation::finished,
            [this](){ this->hide(); });
}

アニメーションをトリガーするためのカスタム・シグナルshown は、showEvent メソッドから発信されます:

void FullScreenNotification::showEvent(QShowEvent *event)
{
    QLabel::showEvent(event);
    if (!m_previouslyVisible && isVisible())
        emit shown();
    m_previouslyVisible = isVisible();
}

プロジェクト例 @ code.qt.io

本ドキュメントに含まれる文書の著作権は、それぞれの所有者に帰属します。 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。