mardi 21 avril 2015

Qt main window destructor not called on exit?

I am coding a fairly simple application that uses Qt with OpenCV. I have single window that contains a widget which displays a video feed captured from a webcam. The webcam video capture is running in an infinite loop in a separate thread so as not to consume the UI thread.

When I close the window (using the normal "X" button on the top right of the window - this app is being developed in Windows 7), it doesn't seem to be shutting down the program correctly. The window does close visibly, but I put a breakpoint in the destructor of the main window, and the breakpoint never gets hit. Additionally, the thread which does video capture continues to run (I know this because the thread outputs to stdout periodically). Only when I click "stop debugging" in the Qt development environment does it cause everything to completely shut down.

Here is my worker object (not subclassing from 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);
};

Here is the header file for my main window:

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;
};

And the class implementation:

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);
}

Any help understanding why the program doesn't shut down properly would be appreciated. Thanks!

Aucun commentaire:

Enregistrer un commentaire