退出时没有调用Qt主窗口析构函数?

时间:2015-04-21 19:31:29

标签: c++ multithreading qt qthread qtgui

我正在编写一个使用Qt和OpenCV的相当简单的应用程序。我有一个窗口,其中包含一个小部件,显示从网络摄像头捕获的视频。网络摄像头视频捕获在一个单独的线程中以无限循环运行,以便不使用UI线程。

当我关闭窗口时(使用窗口右上角的正常“X”按钮 - 此应用程序正在Windows 7中开发),它似乎没有正确关闭程序。窗口确实关闭,但我在主窗口的析构函数中放置了一个断点,断点永远不会被击中。另外,进行视频捕获的线程继续运行(我知道这是因为线程定期输出到stdout)。只有当我在Qt开发环境中单击“停止调试”时,它才会导致所有内容完全关闭。

这是我的工作者对象(不是来自QThread的子类):

class Worker : public QObject
{
    Q_OBJECT
private:
    VideoCapture *cap;
    bool finished;
    QMutex mutex;
public:
    Worker ()
    {
        cap = new VideoCapture(0);
        finished = false;
    }

    bool isFinished ()
    {
        QMutexLocker locker (&mutex);
        return finished;
    }

public slots:
    void doWork ()
    {
        Mat frame;
        while(!isFinished())
        {
            // ...some code that outputs to stdout deleted for clarity...
            (*cap) >> frame;
            emit resultReady(frame);
        }
    }

    void setFinished (bool f)
    {
        QMutexLocker locker (&mutex);
        finished = f;
    }

signals:
    void resultReady (Mat frame);
};

这是我主窗口的头文件:

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    CVImageWidget* imageWidget;
    Worker *worker;
    QThread workerThread;

public slots:
    void handleResults (Mat frame);

signals:
    void operate ();
    void finishSignal (bool f);

private:
    Ui::MainWindow *ui;
};

类实现:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    //Create a widget for this window.
    QWidget *wdg = new QWidget(this);
    QGridLayout *grid = new QGridLayout(wdg);

    // ...code creating widgets deleted for clarity...

    this->setCentralWidget(wdg);

    //Start video capture
    qRegisterMetaType<Mat>("Mat");
    worker = new Worker();
    worker->moveToThread(&workerThread);
    connect(&workerThread, SIGNAL(finished()), worker, SLOT(deleteLater()));
    connect(this, SIGNAL(operate()), worker, SLOT(doWork()));
    connect(worker, SIGNAL(resultReady(Mat)), this, SLOT(handleResults(Mat)));
    connect(this, SIGNAL(finishSignal(bool)), worker, SLOT(setFinished(bool)));

    workerThread.start();
    emit operate();
}

MainWindow::~MainWindow()
{
    emit finishSignal(true);
    workerThread.quit();
    workerThread.wait();
    delete ui;
}

void MainWindow::handleResults(Mat frame)
{
    imageWidget->showImage(frame);
}

任何帮助理解程序未正确关闭的原因将不胜感激。谢谢!

0 个答案:

没有答案