QThread: Destroyed while thread is still running?
Solution 1
As the error message states: QThread: Destroyed while thread is still running
. You are creating your SamplingThread
object inside the MainWindow::start
method but it goes out of scope (i.e. is destroyed) when that method terminates. There are two easy ways that I see:
- You make your
SamplingThread
a member of yourMainWindow
so its lifetime is the same as for theMainWindow
instance You use a pointer, i.e. you create the
SamplingThread
usingSamplingThread *samplingThread = new SamplingThread;
Does this help?
Edit: to illustrate the two cases, a very crude example to show the two cases
#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();
}
Solution 2
This is basics of C++! You are creating local object of QThread
on stack not on heap, so it gets destroys immediately when you leave method MainWindow::start
.
It should be done like that:
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);
}
Solution 3
There are two different "threads" involved: One is the actual thread, the other is the C++ object representing it (and to be correct, there is another thread from which this code is started in the first place).
The error just says that the thread is still running at the point where the C++ object representing it is destroyed. In your code, the reason is that the QThread instance is local to start()
. Maybe you want to store the QThread in a member.
The Man
Updated on October 30, 2020Comments
-
The Man over 3 years
I would like to start my
QThread
when I push on button Run. But the compiler outputs following error:QThread: Destroyed while thread is still running ASSERT failure in QThread::setTerminationEnabled(): "Current thread was not started with QThread.", file thread\qthread_win.cp.
I don't know what is wrong with my code.
Any help would be appreciated.
Here is my code:
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; }
-
Kuba hasn't forgotten Monica almost 10 yearsThe
SamplingThread
is created in the first line ofMainWindow::start
, then started, then immediately destroyed while it is still running as thestart
returns. The error message tells you what's wrong, and C++ semantics tell you why it's so. This question has not much to do with Qt, all to do with understanding of the semantics of the programming language that you are using.
-
-
Erik almost 10 yearsFor solution. 2. you can pretty much take what I wrote. You then have to replace the '.' accesses to the object by '->' to access the methods of the underlying object (if this doesn't mean anything to you, I strongly suggest to go through some more c++ basic tutorials e.g some of those suggested here stackoverflow.com/questions/388242/…). For 1:I don't know the code of your MainWindow but in general you declare the object e.g. as private member your class and then initialize it in a en.cppreference.com/w/cpp/language/initializer_list
-
Erik almost 10 yearsAgain, if you don't know what a member of a class is, you should really read more about this (e.g here to pick one of many many possibilities: cplusplus.com/doc/tutorial/classes). If you go the second way you only set the frequency and call the run method in MainWindow::start method as the object has been created already in the initializer list
-
The Man almost 10 yearsof course , I Known what member of class is or how i can acess to a method, actually , my comment was not for you , I have another question on this forum and I wanted the code. anway thank you for the link about the book
-
The Man almost 10 yearsThank you. its works now fine.. I have a general question now, I dont used to initialise all the member of my class like you before to use it . is it dangerous ?
-
Ahmad Sarabian over 7 yearsThanks, this is complete.