views:

170

answers:

3

Ok, so I'm having this problem tonight:

[...]   

connect(startButton, SIGNAL(clicked()), this, SLOT(startCalculation()));
connect(stopButton, SIGNAL(clicked()), this, SLOT(stopCalculation()));

[...]

void MainWindow::startCalculation()
{
   qDebug() << "hello";
   this->startButton->setDisabled(true);
   this->stopButton->setEnabled(true);
   this->calcStatus = true;
   this->calculate();
}

void MainWindow::stopCalculation()
{
    this->startButton->setEnabled(true);
    this->stopButton->setDisabled(true);
    this->calcStatus = false;
}


void MainWindow::calculate()
{
   qDebug() << "hello";
   while(this->calcStatus)
   {
   }
}
[...]

I'm trying to make the calculate() procedure stoppable any time, but right after it is started I loose control and I can't press STOP. Of course in my future plans calculate() is going to "calculate" something real (e.g. heat transfer simulation).

Thanks for suggestions. P.

A: 

You would need to look into threading. The calculation locks the ui.

Andrei Tanasescu
A: 

Well, in "Introduction to Design Patterns in C++ with Qt4" they say that

"it is possible to avoid the use of threads in favor of the Qt Event Loop combined with QTimers"

but I've never tried it :)

Actually, I've just tried -

add:

QTimer      *Timer;

in MainWindow class header and in MainWindow constructor add:

Timer = new QTimer(this);

then change calculate() from function to a signal and modify:

void MainWindow::startCalculation()
{
    qDebug() << "hello";
    this->startButton->setDisabled(true);
    this->stopButton->setEnabled(true);
    this->calcStatus = true;
    connect(Timer, SIGNAL(timeout()), this, SLOT(calculate()));
    Timer->start(0);
}

void MainWindow::stopCalculation()
{
    this->startButton->setEnabled(true);
    this->stopButton->setDisabled(true);
    this->calcStatus = false;
    Timer->stop();
    Timer->disconnect(this,SLOT(calculate()));
}

This should work as long as you dont pass any arguments into calculate().

funny man
This only works well if you can break calculate into discrete steps, and repeatedly call the timer function on it if you need to continue calculating whatever. Also, you don't need to keep the QTimer pointer... there is a convenience function inside QTimer to do this: "QTimer::singleshot( 0, this, SLOT(calculate() );".
Caleb Huitt - cjhuitt
A: 

I don't get pkajak's answer. Andrei is correct. You need to look into threading.

cheez