当我按下运行按钮时,我想启动QThread
。但编译器输出以下错误:
QThread: Destroyed while thread is still running
ASSERT failure in QThread::setTerminationEnabled(): "Current thread was not started with QThread.", file thread\qthread_win.cp.
我不知道我的代码有什么问题。
任何帮助都将不胜感激。
这是我的代码:
SamplingThread::SamplingThread( QObject *parent):
QwtSamplingThread( parent ),
d_frequency( 5.0 )
{
init();
}
MainWindow::MainWindow( QWidget *parent ):
QMainWindow( parent )
{.......
.....
run= new QPushButton ("Run",this);
stop= new QPushButton("Stop",this);
connect(run, SIGNAL(clicked()),this, SLOT (start()));
}
MainWindow::start
{
SamplingThread samplingThread;
samplingThread.setFrequency( frequency() );
samplingThread.start();
}
int main( int argc, char **argv )
{
QApplication app( argc, argv );
MainWindow window;
window.resize( 700, 400 );
window.show();
bool ok = app.exec();
return ok;
}
答案 0 :(得分:20)
如错误消息所示:QThread: Destroyed while thread is still running
。您正在SamplingThread
方法中创建MainWindow::start
对象,但当该方法终止时,它会超出范围(即被销毁)。我看到了两种简单的方法:
SamplingThread
成为MainWindow
的成员,因此其生命周期与MainWindow
实例您使用指针,即使用
创建SamplingThread
SamplingThread *samplingThread = new SamplingThread;
这有帮助吗?
编辑:为了说明这两种情况,一个非常粗略的例子来说明这两种情况
#include <iostream>
#include <QApplication>
#include <QThread>
class Dummy
{
public:
Dummy();
void start();
private:
QThread a;
};
Dummy::Dummy() :
a()
{
}
void Dummy::start()
{
a.start();
QThread *b = new QThread;
b->start();
if( a.isRunning() ) {
std::cout << "Thread a is running" << std::endl;
}
if( b->isRunning() ) {
std::cout << "Thread b is running" << std::endl;
}
}
int main(int argc, char** argv)
{
QApplication app(argc,argv);
Dummy d;
d.start();
return app.exec();
}
答案 1 :(得分:4)
这是C ++的基础知识!您正在堆栈上创建QThread
的本地对象,而不是在堆上,因此当您离开方法MainWindow::start
时它会立即销毁。
应该这样做:
MainWindow::MainWindow( QWidget *parent ):
QMainWindow( parent )
{
...
samplingThread = SamplingThread(this);
samplingThread->setFrequency( frequency() );
run= new QPushButton ("Run",this);
stop= new QPushButton("Stop",this);
connect(run, SIGNAL(clicked()), samplingThread, SLOT(start()));
}
MainWindow::~MainWindow() {
samplingThread->waitFor(5000);
}
答案 2 :(得分:2)
涉及两个不同的“线程”:一个是实际线程,另一个是表示它的C ++对象(并且正确,首先从另一个线程启动此代码)。
错误只是说线程仍然在代表它的C ++对象被销毁的位置运行。在您的代码中,原因是QThread实例是start()
的本地实例。也许您想将QThread存储在成员中。