2015-04-19 237 views
0

我想實現一個多線程的應用程序,顯示視頻使用OpenCV庫(下面的例子給出here)。Qt應用程序仍然運行後關閉MainWindow

我從GUI線程創建兩個線程,在MainWindow關閉時成功終止。但是,程序仍然繼續運行(我必須使用應用程序輸出面板上的停止按鈕關閉它)。

這裏是我的主窗口

MainWindow::~MainWindow() 
{ 

captureThread.quit(); 
converterThread.quit(); 

if (captureThread.wait()) 
     qDebug() << "Capture Thread has exited successfully"; 

if (converterThread.wait()) 
     qDebug() << "Converter Thread has exited successfully"; 

delete ui; 
} 

應用程序的輸出窗口返回兩個調試以下輸出的析構函數和發佈版本

Capture Thread has exited successfully 
Converter Thread has exited successfully 

但是,應用程序只能在調試模式下退出。

從我從幾個谷歌搜索收集的是,應用程序繼續運行,如果有一個線程沒有正確終止。這可能是這種情況嗎?如果是,那麼我怎麼知道哪個其他線程也在程序中運行,以便我可以終止/退出?

使用Qt 5.4用MSVC 2013和OpenCV 3.0測試版在Win 8.1

編輯 創建我的主窗口構造線程

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

// registers the type cv::Mat. After a type is registered, one can create/destroy objects at runtime 
qRegisterMetaType<Mat>(); 

// Initializing class' instance 
Capture* capture = new Capture; 
Converter* converter = new Converter; 

ui->labelFrame->setAttribute(Qt::WA_OpaquePaintEvent); 
converter->setProcessAll(false); 

capture->moveToThread(&captureThread); 
converter->moveToThread(&converterThread); 


converter->connect(capture, SIGNAL(matReady(Mat)), converter, SLOT(processFrame(Mat))); 
this->connect(converter, SIGNAL(imageReady(QImage)), this, SLOT(setImage(QImage))); 

// thread clean up 
connect(&captureThread, SIGNAL(finished()), &captureThread, SLOT(deleteLater())); 
connect(&converterThread, SIGNAL(finished()), &converterThread, SLOT(deleteLater())); 

QObject::connect(capture, &Capture::started, 
       [](){ qDebug() << "capture started"; }); 

QMetaObject::invokeMethod(capture, "start"); 

captureThread.start(); 
converterThread.start(); 

編輯2:我修改了我的main.cpp至此

QApplication a(argc, argv); 
MainWindow w; 
w.show(); 

int ret; 
ret = a.exec(); 
qDebug() << "QApplication.exec() returns " << ret; 
return ret; 

我收到以下g消息

QApplication.exec() returns 0 
Capture Thread has exited successfully 
Converter Thread has exited successfully 

這是令人困惑的,因爲QApplication應該在線程停止後退出。所以我將線程清理移至abouttoQuit()插槽。退出的順序已通過此修改而改變,但原始問題依然存在。 (順序錯誤可能是由於qDebug()函數的實現,但是那只是我的猜測)

PS我甚至在析構函數中添加captureThread.terminate()converterThread.terminate()但還是結果都是一樣的。

+0

顯示你的線程代碼,並創建它們的代碼。 – dtech

+1

你可以向我們展示創建和銷燬MainWindow的主要方法嗎? –

+0

@SimonWarta調用MainWindow的主要方法是標準的Qt代碼。我沒有觸及它 – user3079474

回答

1

問題

好吧,原來是內存泄漏。在我的MainWindow的構造函數中,我宣佈並初始化了converter *capture *類的兩個實例。然而,當構造函數結束它的範圍時,這些指針從來沒有被釋放。

解決方案

免費在CleanUp()功能的存儲器。 (該CleanUp()功能連接到應用程序的aboutToQuit()插槽。要對清理()函數訪問的指針,它們聲明爲MainWindow類的成員。

0
QMetaObject::invokeMethod(capture, "start"); 

看起來很可疑。你可以將其替換爲:

connect(&captureThread, &QThread::started, capture, &Capture::start); 

而且,沒有必要做線程清理,因爲它們是主窗口類的成員,將與它被破壞,刪除這兩條線:

connect(&captureThread, SIGNAL(finished()), &captureThread, SLOT(deleteLater())); 
connect(&converterThread, SIGNAL(finished()), &converterThread, SLOT(deleteLater())); 
+0

我不這麼認爲'QMetaObject :: invokeMethod(capture,「start」);'正在導致問題,正如解釋[here](http:// stackoverflow的.com /問題/ 13948337 /爲什麼-使用-qmetaobjectinvokemethod-時執行的-方法-從線程) – user3079474

相關問題