You have declared your thread object on the stack, here:
void MainWindow::on_button_run_clicked()
{
Stepper1_run stepper1_run; // <- Stepper1_run is instantiated
stepper1_run.system_run(); // <- Thread starts
} // <- stepper1_run goes out of scope and is destroyed.
The object is being destroyed as soon as it goes out of scope, which happens immediately after you call system_run()
, hence the error.
Making it a class member is one option. You can make it a pointer (or one of the Qt auto pointers); this is appropriate if you can only have one instance of this thread running at a time. To start the thread, instantiate a Stepper1_run
, start it, and store the pointer. To stop the thread, signal it to stop, join on it, then delete the instance and reset the pointer. Be sure to stop the thread before destroying it when the containing class is destroyed as well (you can perform your usual stop -> join -> delete logic in the containing class destructor).
Update; example as requested in comments:
class MainWindow : ... {
...
public:
~MainWindow ();
public slots:
void startSystem ();
void stopSystem ();
private:
QScopedPointer<Stepper1_run> stepper_;
};
MainWindow::~MainWindow () {
stopSystem(); // <- proper termination of thread on exit
}
void MainWindow::startSystem () {
stopSystem();
stepper_.reset(new Stepper1_run());
stepper_->system_run();
}
void MainWindow::stopSystem () {
if (stepper_) {
stepper_->whateverStopsTheThread(); // <- you'd need to implement this
stepper_->wait(); // <- i.e. join; waits for thread to terminate
stepper_.reset(); // <- i.e. delete
}
}
That example is one of many possibilities, and your scenario may differ. Also error handling / exception-safety has been omitted for brevity (and details of that also depend on your situation). Above example assumes for simplicity that only one thread should be running, and that starting a new one should terminate the old one.
Note, by the way, that by using slots, you can simply connect()
your button's clicked()
signal to startSystem()
. This also provides you with a means to call startSystem()
and stopSystem()
from other threads and let Qt take care of the synchronization details.
Use a QSharedPointer
if you intend to pass pointers to the thread around to other objects (it has a slightly different API from QScopedPointer
, so read the documentation). Use a C-style pointer if you want to for some reason, it is similar to a QScopedPointer
in the above situation, just remember to initialize it to NULL
in the MainWindow
constructor if you do.