你可以通过下面这种方式创建一个播放器组件:
QVBoxLayout* mainLayout = new QVBoxLayout(centralWidget);
mainLayout->setSpacing(0);
mainLayout->setContentsMargins(0, 0, 0, 0);
auto videoWidget = new QVideoWidget(this);
mainLayout->addWidget(videoWidget);
auto player = new QMediaPlayer(this);
auto pathUrl = QUrl::fromLocalFile(videoPath);
player->setSource(pathUrl);
player->setVideoOutput(videoWidget);
player->play();
但你很难在这个视频播放组件上放置一个按钮,像下面这样,视频上有一个播放按钮。
这是为什么呢?
因为自Qt 6以来,QVideoWidget 默认使用硬件加速渲染,而 QWindow 和 QWidget 仍旧还是软渲染,Qt为了能把硬件加速的内容渲染到 QWindow 和 QWidget 上,使用的是子窗口的技术,也就是说,QVideoWidget 相当于一个子窗口,你想通过父窗口在这个子窗口上面放置一个(画一个)按钮,几乎是不可能的。
详细的讨论请参见这里:Button over QVideoWidget | Qt Forum
那么怎么解决这个问题呢?
你应该用:QGraphicsVideoItem 来解决这个问题,让我们看看代码:
QVBoxLayout* mainLayout = new QVBoxLayout(centralWidget);
mainLayout->setSpacing(0);
mainLayout->setContentsMargins(0, 0, 0, 0);
view = new QGraphicsView(centralWidget);
view->setBackgroundBrush(QBrush(Qt::white));
view->setFrameStyle(QFrame::NoFrame);
view->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
view->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
scene = new QGraphicsScene(view);
view->setScene(scene);
mainLayout->addWidget(view);
viewBtn = new QPushButton(this);
viewBtn->setFixedSize(54, 54);
viewBtn->setStyleSheet("background:rgba(0,0,0,76);border:none;border-radius:27px;width:54px;height:54px;color:#fff;font-size:36px;text-align:center;");
QFont& iconFont = *IconFont::get();
viewBtn->setFont(iconFont);
viewBtn->setText(QChar(0xe77d));
scene->addWidget(viewBtn);
mainLayout->activate();
在这段代码里,我们创建了QGraphicsView、QGraphicsScene以及覆盖在视频上面的按钮:viewBtn
现在来看看如何播放视频:
video = new QGraphicsVideoItem();
video->setAspectRatioMode(Qt::KeepAspectRatio);
scene->addItem(video);
player = new QMediaPlayer(this);
auto audioOutput = new QAudioOutput(this);
player->setAudioOutput(audioOutput);
auto pathUrl = QUrl::fromLocalFile(videoPath);
player->setSource(pathUrl);
player->setVideoOutput(video);
player->play();
至此,就在视频组件上放置了一个按钮。