【问题标题】:Deleting QCamera crashes program删除 QCamera 崩溃程序
【发布时间】:2014-02-27 00:07:54
【问题描述】:

我正在使用 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 的析构函数中,你可以看到我已经注释掉了删除相机的行。当我像这样运行程序时,它运行良好(我尝试过发布和调试模式),我可以根据需要多次显示和关闭对话框而不会崩溃。当我取消注释这一行时,调用析构函数时程序意外崩溃。

我正在使用

启动对话框
CameraTestDialog *dlg = new CameraTestDialog();
dlg->show();

我很高兴将 delete camera 行注释掉,以便我的程序运行,但这是否意味着每次关闭对话框时我都会泄漏内存?停止和删除 QCamera 对象的正确方法是什么?

我在 Mavericks 下的 2012 年 Mac Book Air 上运行,使用 QT Creator 2.8.1。


编辑:

我没有安装调试器,因此我目前没有更多关于崩溃性质的信息。

我怀疑camera-&gt;stop()camera-&gt;unload() 调用的行为是异步的,因此相机在实际停止之前就被删除了。为了测试这一点,我添加了 while 循环来检查相机的状态,并阻塞直到相机被确认停止并卸载。我发现这些函数实际上是同步的,并且仍然有相同的症状(在调用 delete 后一段时间崩溃)。


编辑 2:

我尝试将对相机的引用更改为基于堆栈,而不是基于new,并删除了删除行。执行此操作后,程序在构造函数期间崩溃,在显示对话框之前。


编辑 3:

我刚刚确认该程序在 Windows 7 上不会崩溃,因此我假设这是 OSX 计算机上 QCamera 的 QT 实现中的低级错误。我将尝试在 QT 项目中提出一个错误。

【问题讨论】:

  • 在调用delete ui;后尝试调用delete camera;
  • 感谢您的建议,刚刚尝试过,它具有相同的症状(在析构函数期间崩溃)。我还尝试将删除行更改为 camera-&gt;deleteLater() 并得到相同的结果。
  • 我不太清楚这里发生了什么,但你可以试试camera = new QCamera(this)。这将使相机成为您对话类的子级。删除对话框时应该会自动删除。
  • 感谢@AlexP 的建议。我试过了,效果一样。
  • 这可能不会影响您的程序,但是在您的构造函数中,将 camera 设置为 0,删除 camera (即一个空指针),然后初始化 camera?

标签: c++ macos qt camera crash


【解决方案1】:

奇怪的是,我刚刚确定这确实是 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项目提交一个bug我已经向Qt项目提交了QTBUG-37109

【讨论】:

    【解决方案2】:

    问题是 QCamera 似乎在线程中运行。 “过早”删除它会导致 Windows 上出现 QMutuex 错误。因此,解决方案是camera-&gt;stop(); 而不是camera-&gt;unload();

    最后也是最重要的:使用 delete camera 代替

    camera->deleteLater();
    

    【讨论】:

      猜你喜欢
      • 2011-12-08
      • 1970-01-01
      • 2016-08-08
      • 2014-07-16
      • 2018-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多