原文地址
前言
Qt6
相对Qt5
的接口变化非常大,很多Qt5
的网络信息已经不适用了,需要自己去官方文档和官方示例项目里面慢慢摸索,相机方面的改动也是非常大,这里简单说下使用Qt6
相机的两个方法
使用QVideoWidget
在官方的相机示例项目中,使用的是QVideoWidget
作为相机的输出源,核心代码如下
//h
class Camera : public QWidget
{
//...
QScopedPointer<QCamera> m_camera;
QMediaCaptureSession m_captureSession;
QVideoWidget* m_view;
//...
}
//cpp
Camera::Camera(QWidget* parent) : QWidget{ parent }
{
//...
m_view = new QVideoWidget(this);
m_view->resize(1920, 1080);
const QList<QCameraDevice> cameras = QMediaDevices::videoInputs();
if (!cameras.isEmpty()) {
auto thisCamera = new QCamera(cameras.first());
m_camera.reset(thisCamera);
m_captureSession.setCamera(m_camera.data());
m_captureSession.setVideoOutput(m_view)
}
//...
}
//
void Camera::startPlay()
{
camera->startPlay();
}
作为官方推荐的,这个东西相当难用,可能是我没找对方法,但是方法不能被容易的发现也是难用。首先最重要的,它的播放模式是contain
,所以如果在比例不对的情况下会有黑边,我没有找到如何切换它的播放模式改变为cover
那么我们就寻思自己去覆盖,使用resizeEvent
和负起始坐标手动改为cover
,结果还是不行。因为QVideoWidget
上播放的东西z轴
优先级是最高,无法通过负起始坐标来手动cover,因为它甚至可以突破父组件的限制到兄弟组件的位置去。故始终没有在Qt6
下找到合适简单的方法可以以QVideoWidget
完成cover
播放,最后选择使用QGraphicsVideoItem
完成播放。但是如果你不介意播放模式是contain
,或者就想要这样的,那么QVideoWidget
应该是更好的选择,根据文档的说法,它的性能会更高
使用QGraphicsVideoItem
核心代码如下
//h
class Wid : public QWidget
{
//...
private:
QScopedPointer<QCamera> m_camera;
QMediaCaptureSession m_captureSession;
QGraphicsVideoItem* m_graphicsVideoItem;
QGraphicsView* m_cameraView;
QGraphicsScene* m_cameraScene;
//...
}
//cpp
Camera::Camera(QWidget* parent) : QWidget{ parent }
{
initLayout();
initCamera();
//..
}
//...
void Camera::initLayout()
{
QVBoxLayout* mainLayout = new QVBoxLayout(this);
mainLayout->setSpacing(0);
mainLayout->setContentsMargins(0, 0, 0, 0);
m_cameraScene = new QGraphicsScene();
m_cameraView = new QGraphicsView(m_cameraScene);
m_cameraView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_cameraView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_cameraView->setScene(m_cameraScene);
mainLayout->addWidget(m_cameraView);
m_graphicsVideoItem = new QGraphicsVideoItem();
// m_graphicsVideoItem->setSize(QSizeF(865, 487));
m_captureSession.setVideoOutput(m_graphicsVideoItem);
m_cameraScene->addItem(m_graphicsVideoItem);
}
void Wid::initCamera()
{
const QList<QCameraDevice> cameras = QMediaDevices::videoInputs();
if (cameras.isEmpty())
{
// todo throw
}
auto thisCamera = new QCamera(cameras.first());
m_camera.reset(thisCamera);
m_captureSession.setCamera(m_camera.data());
}
//...