PDA

View Full Version : QTimer and QTimeLine



martisho
20th November 2009, 13:23
Hi all,

please I need your help. What I want to do is, the user introduce in a form a total time of running, and an interval time. In each interval of the total time, several values are sent and several values are received. In a progress bar the total time is showed.

When someone pressed the stop button or the total time is finished, it calls a function that stop the timeline and the timer and call another function that shows a file dialog to save all the values in a XML.

The problem is that there is something worng in the timer or in the timeline, because when i run and then press the stop button, the file dialog is shown, but if i cancel the file dialog quick, another file dialog is shown, is like the stopall function is called several times. When the progrees bar end, it don´t happen.

Here is the code:


void Controller_run::execute(){

int frequency = run->ui.leFrequency->text().toInt();
int total = run->ui.leTotal->text().toInt();

timerFrequency = new QTimer(this);
timeLine = new QTimeLine;

timeLine->setDuration(total);
timeLine->setFrameRange(0, 150); // update every second
timeLine->setLoopCount(1);

run->ui.progressBar->setRange(0, 150);

connect(timerFrequency, SIGNAL(timeout()), this, SLOT(send_receive()));
connect(timeLine, SIGNAL(frameChanged(int)), run->ui.progressBar, SLOT(setValue(int)));
run->ui.progressBar->setValue(0);
connect(run->ui.btStop, SIGNAL (clicked()), this, SLOT(stopall()));
connect(timeLine, SIGNAL(finished()), this, SLOT(stopall()));

timerFrequency->start(frequency);
timeLine->start();
}

void Controller_run::stopall(){

timerFrequency->deleteLater();
timeLine->stop();

run->ui.btRun->setEnabled("true");
run->ui.btStop->setDisabled("true");

save_xml_file();
}

Please help me, i am desperated.

Thanks in advanced.

high_flyer
20th November 2009, 13:39
Try this:


void Controller_run::stopall(){
timerFrequency->stop();
timerFrequency->deleteLater();
timeLine->stop();

run->ui.btRun->setEnabled("true");
run->ui.btStop->setDisabled("true");

save_xml_file();
}


P.S
This is not good practice:


timerFrequency = new QTimer(this);
timeLine = new QTimeLine;


in a slot, since each time this slot is called a new instance for the timer and timeline is allocated, where as the old one is still alive (unless you made sure to delete them before this slot is called).
It is better to put initialization in the constructor or an init() function which is called once at start.

martisho
24th November 2009, 09:16
Hello high_flyer,

i have tryed what you said, but it doesn´t work, it happens the same, if i press the stop button quickly the function calls save dialog, if i cancel the save dialog, quickly, another save dialog is shown, the stopall is called several times.

I delete QTimer and QTimeLine, in the stopall function, but as this function is called several times, it occurs an error because is trying to delete QTimer that it doesn´t exists.

Another idea please!!

high_flyer
24th November 2009, 14:29
i have tryed what you said, but it doesn´t work, it happens the same, if i press the stop button quickly the function calls save dialog, if i cancel the save dialog, quickly, another save dialog is shown, the stopall is called several times.
I think I know why - its because your stopall() is called both by the button and by the timer.
So if you click the button, before the timer times out, the slot will be called twice.


I delete QTimer and QTimeLine, in the stopall function, but as this function is called several times, it occurs an error because is trying to delete QTimer that it doesn´t exists.
Right, which is why I wrote in the previous post:

It is better to put initialization in the constructor or an init() function which is called once at start.