2015-04-19 238 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

相关问题