我正在使用 QT 和 QCamera 对象在对话框中显示来自摄像机的视频。我的代码如下;
cameratestdialog.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CameraTestDialog</class>
<widget class="QDialog" name="CameraTestDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QCameraViewfinder" name="viewfinder" native="true">
<property name="geometry">
<rect>
<x>40</x>
<y>40</y>
<width>281</width>
<height>201</height>
</rect>
</property>
</widget>
</widget>
<customwidgets>
<customwidget>
<class>QCameraViewfinder</class>
<extends>QWidget</extends>
<header>qcameraviewfinder.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
cameratestdialog.h
#ifndef CAMERATESTDIALOG_H
#define CAMERATESTDIALOG_H
#include <QDialog>
#include <QCamera>
namespace Ui {
class CameraTestDialog;
}
class CameraTestDialog : public QDialog
{
Q_OBJECT
public:
explicit CameraTestDialog(QWidget *parent = 0);
~CameraTestDialog();
private:
Ui::CameraTestDialog *ui;
QCamera *camera;
};
#endif // CAMERATESTDIALOG_H
cameratestdialog.cpp
#include "cameratestdialog.h"
#include "ui_cameratestdialog.h"
#include <QCameraViewfinder>
#include <QDebug>
CameraTestDialog::CameraTestDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::CameraTestDialog),
camera(0)
{
ui->setupUi(this);
this->setAttribute(Qt::WA_DeleteOnClose);
delete camera;
camera = new QCamera;
camera->setViewfinder(ui->viewfinder);
camera->start();
}
CameraTestDialog::~CameraTestDialog()
{
qDebug() << "Stopping Camera";
camera->stop();
camera->unload();
//delete camera;
delete ui;
}
在cameratestdialog.cpp
的析构函数中,您可以看到我已经注释掉了删除相机的行。当我像这样运行程序时它工作正常(我已经尝试过发布和 Debug模式),我可以根据需要多次显示和关闭对话框而不会崩溃。当我取消注释这一行时,程序在调用析构函数时意外崩溃。
我正在启动对话
CameraTestDialog *dlg = new CameraTestDialog();
dlg->show();
我很高兴对 delete camera
行进行注释以便我的程序运行,但这是否意味着每次关闭对话框时我都会泄漏内存?停止和删除 QCamera 对象的正确方法是什么?
我在 Mavericks 下的 2012 时代 Mac Book Air 上运行,使用 QT Creator 2.8.1。
编辑:
我没有安装调试器,所以目前我没有任何关于崩溃性质的更多信息。
我怀疑 camera->stop()
和 camera->unload()
调用行为不同步,因此相机在实际删除之前就被删除了停了。为了对此进行测试,我添加了 while 循环来检查相机的状态,并阻塞直到相机被确认停止并卸载。我发现这些函数实际上是同步的,并且仍然有相同的症状(调用删除后一段时间崩溃)。
编辑 2:
我尝试将对相机的引用更改为基于堆栈的引用,而不是基于 new
的引用,并删除了删除行。这样做之后,在显示对话框之前,程序在构造函数期间崩溃。
编辑 3:
我刚刚确认该程序不会在 Windows 7 上为我崩溃,因此我假设这是 OSX 计算机上 QCamera 的 QT 实现中的低级错误。我将尝试提出 QT 项目的错误。
最佳答案
奇怪的是,我刚刚确定这确实是 OSX 上的某种异步问题。当我允许对话框在删除相机对象之前处理事件至少 19 毫秒时,程序不会崩溃。这向我表明,OSX QCamera
实现需要一段时间才能完全关闭/断开与某处硬件的连接。
CameraTestDialog::~CameraTestDialog()
{
qDebug() << "Stopping Camera";
camera->stop();
camera->unload();
QTime dieTime = QTime::currentTime().addMSecs(19);
while(QTime::currentTime() < dieTime) {
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
}
delete camera;
delete ui;
}
请注意,对话框需要在此等待期间处理事件,简单地将一些文本打印到屏幕上会导致它仍然崩溃。此外,任何小于 19 毫秒的时间都会导致它仍然崩溃。
显然这是一个 hack 解决方案,所以 我要向 QT 项目提交一个错误 我已经提交了 QTBUG-37109到 Qt 项目。
关于c++ - 删除QCamera崩溃程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22056348/