无标题
- 开启摄像头三步走
-
- 第一步UI界面,自己画的
- [第二步 定义对象](#第二步 定义对象)
- [第三步 实现功能](#第三步 实现功能)
- 后面还有踩得坑记录一下。。。
开启摄像头三步走
第一步UI界面,自己画的
第二步 定义对象
一个UI
一个摄像头
一个用来显示摄像头的
一个list存储摄像头名称
一个捕捉信息的
一个用来存储名字的
函数分别为 开启 拍照 保存 关闭
cpp
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_face.h"
#include <QMainWindow>
#include <QCamera>
#include <QCameraViewfinder>
#include <QCameraImageCapture>
#include <QCameraInfo>
#include <QDateTime>
#include <QMessageBox>
class face : public QMainWindow
{
Q_OBJECT
public:
face(QWidget *parent = Q_NULLPTR);
~face();
private slots:
void on_startBt_clicked();
void on_photographBt_clicked();
void take_photo(int id, const QImage &image);
void close_bt_clicked();
private:
Ui::faceClass ui;
//摄像头对象指针
QCamera* Camera;
//摄像头的取景器
QCameraViewfinder* CameraViewFinder;
//存储摄像机设备信息
QList<QCameraInfo> CameraInfoList;
//记录摄像头内容
QCameraImageCapture* CameraImageCapture;
//照片的名字
QString ImageName;
};
第三步 实现功能
1 将摄像头信息存储在容器中
2 信号与槽建立连接
3 开始函数 初始化摄像头,视图绑定,将捕获信号绑定保存函数
4 拍照函数 发送捕获信号 使得上一步的槽函数触发
5 关闭 显示器关闭,摄像头停止
cpp
#include "face.h"
face::face(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
CameraInfoList = QCameraInfo::availableCameras();
//遍历,将摄像头信息逐个添加到下拉列表当中
QList<QCameraInfo>::const_iterator it;
for (it = CameraInfoList.begin(); it != CameraInfoList.end(); it++)
{
ui.comboBox->addItem((*it).description());
}
Camera = nullptr;
CameraViewFinder = nullptr;
connect(ui.pushButton, &QPushButton::clicked, this, [=] {
on_startBt_clicked();
});
connect(ui.pushButton_2, &QPushButton::clicked, this, [=] {
on_photographBt_clicked();
});
connect(ui.pushButton_3, &QPushButton::clicked, this, [=] {
close_bt_clicked();
});
}
face::~face() {
// delete Camera;
// delete CameraViewFinder;
Camera = nullptr;
CameraViewFinder = nullptr;
//delete ui;
}
void face::close_bt_clicked() {
if (CameraViewFinder) {
CameraViewFinder->close();
Camera->stop();
}
}
void face::on_startBt_clicked() {
//获取到要打开的设备的名称
QCameraInfo CameraInfo = CameraInfoList.at(ui.comboBox->currentIndex());
//创建摄像头对象
Camera = new QCamera(CameraInfo);
//创建取景器并将其附在要显示的区域
CameraViewFinder = new QCameraViewfinder(ui.cameralabel);
Camera->setViewfinder(CameraViewFinder);
//调整摄像头数据显示的大小
CameraViewFinder->resize(ui.cameralabel->width(), ui.cameralabel->height());
//显示摄像头取景器
CameraViewFinder->show();
//开启摄像头
Camera->start();
//创建获取一帧数据对象
CameraImageCapture = new QCameraImageCapture(Camera);
//关联图像获取信号 Capture :捕获
connect(CameraImageCapture, &QCameraImageCapture::imageCaptured, this, &face::take_photo);
}
void face::on_photographBt_clicked() {
//发送获取一帧数据的信号
CameraImageCapture->capture();
}
void face::take_photo(int id, const QImage &image) {
//使用系统时间来命名图片的名称,时间是唯一的,图片名也是唯一的
QDateTime dateTime(QDateTime::currentDateTime());
QString time = dateTime.toString("yyyy-MM-dd-hh-mm-ss");
//创建图片保存路径名
QString filename = QString("D:/qt project/vistudio/face/photo/%1.jpg").arg(time);
//保存一帧数据
image.save(filename);
//提示获取到了一帧数据
QMessageBox::information(this, QStringLiteral( "提示:"), QStringLiteral("获取到一帧图片"));
}
后面还有踩得坑记录一下。。。
关于UI对象的定义
直接ai哥解释
在C++中,对于使用new关键字动态分配的对象,通常需要手动释放内存以避免内存泄漏。但是,对于使用Qt框架中的Ui类(通常是通过uic工具从.ui文件生成的),情况有些不同。
首先,我们来解释一下为什么对于指针ui需要释放,而对于非指针ui则不需要。
为什么对于指针ui需要释放?
如果你的ui成员是一个指针(例如Ui::faceClass* ui;),那么它通常是通过new关键字动态分配的。在这种情况下,你必须手动释放内存,否则会导致内存泄漏。内存泄漏是一种常见的编程错误,它会导致程序占用的内存不断增加,最终可能导致程序崩溃或系统资源耗尽。
为什么对于非指针ui不需要释放?
如果你的ui成员不是指针(例如Ui::faceClass ui;),那么它通常是作为类的一个成员变量直接嵌入到对象中的。在这种情况下,ui对象的生命周期与包含它的face对象相同。当face对象被销毁时,ui对象也会自动被销毁,因此你不需要手动释放内存。
然而,在Qt中,通常的做法是将Ui类的成员作为非指针成员包含在类中,而不是使用指针。这是因为Qt的Ui类通常是通过uic工具从.ui文件自动生成的,并且设计为与包含它的类一起使用。在这种情况下,Ui类的实例会自动管理其自己的内存,你不需要(也不应该)手动释放它。
总结一下,对于Qt中的Ui类成员,通常应该将其作为非指针成员包含在类中,而不是使用指针。这样做可以简化内存管理,并避免潜在的内存泄漏问题。如果你确实需要使用指针(例如,如果你需要在多个对象之间共享同一个Ui实例),那么你必须确保正确地管理内存,包括在适当的时候释放内存。
在我的这个程序中
在定义Ui对象的时候 vs+qt是默认不为指针的 也没有析构函数
private:
Ui::faceClass ui;
而在我学习开启摄像头的时候代码是这样的
private:
Ui::faceClass *ui;
这样就导致了需要用到析构函数,否则就会这样
这个情况是因为没有delete ui导致的
还有这样这个,,这个情况是因为delete ui之后导致的, 在我关闭ui之后弹出的断点,,目前还不知道什么情况
指针真是个好东西
关于使用摄像头前提准备
如果你是vs+qt 那么
需要打开 Qt vs tools -> qt project settings -> qt modules -> 添加multimedia multimediawidgets; 否则camera不能使用
还需要注意的是qt版本是否有camera