1

I am making a timer/stopwatch with Qt Creator. But, my reset function (reset button clicked) is not working as I want it to. I want it to stop the timer and set the display (QLCDNumber) to 0. Instead, the timer is stopped but the display numbers stay the same as if the pause button was clicked. Except that when the timer is started (start button clicked) again, it restarts from the original time (as I want it to do). Here is the code.

I only included the parts that are part of the problem.

void MainWindow::delay()
{
    QTime dieTime = QTime::currentTime().addSecs(1);
    while (QTime::currentTime() < dieTime && !spause && !sreset)
    {
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
        std::this_thread::sleep_for(std::chrono::milliseconds(1));
    }
}

void MainWindow::on_tstart_clicked()
{
    ttime = treset ? 0 : ttime;
    tpause = treset = false;
    ttime = ttime == 0 ? (ui->hr->value() * 3600 + ui->min->value() * 60 + ui->sec->value()) : ttime;
    while (ttime >= 0 && !tpause && !treset)
    {
        const unsigned short sec = ttime % 3600 % 60, min = ttime % 3600 / 60, hr = ttime / 3600;
        ui->tsec2->display(sec % 10);
        ui->tsec1->display(sec / 10);
        ui->tmin2->display(min % 10);
        ui->tmin1->display(min / 10);
        ui->thr2->display(hr % 10);
        ui->thr1->display(hr / 10);
        delay();
        if (!tpause && !treset) --ttime;
    }
}

void MainWindow::on_tpause_clicked()
{
    tpause = true;
}

void MainWindow::on_treset_clicked()
{
    treset = true;
    ui->ssec2->display(0);
    ui->ssec1->display(0);
    ui->smin2->display(0);
    ui->smin1->display(0);
    ui->shr2->display(0);
    ui->shr1->display(0);
}
cppxor2arr
  • 295
  • 2
  • 12
  • Pro tips for posting: (a) we don't use [solved] in the title here; (b) post solutions below, rather than as edits; (c) if you solve your original problem but have a new question then don't modify the question, unless the change is very small and you don't yet have any answers. – halfer Jan 17 '17 at 19:33
  • Also, I see you edited some code in your question when you solved it. If that was the problem then please undo it, so that your question is an accurate representation of the problem. There is no point in this site maintaining an answer with no question. – halfer Jan 17 '17 at 19:35
  • @halfer Sorry! Will do as you say. – cppxor2arr Jan 18 '17 at 01:58

3 Answers3

0

Your click on a button is processed only in the function delay() containing processEvents(). When delay() is executed, it sends message to the application, but on_treset_clicked() is executed after the next loop of while() was started. Use QTimer to avoid this situation.

Here is how to use QTimer in your case.

(mainwindow.h)
#include <QTimer>
...
QTimer timer;

(mainwindow.cpp)

MainWindow::MainWindow()
{
    ...
    connect(&timer,SIGNAL(timeout()),this,SLOT(on_timer()));
}

void MainWindow::on_tstart_clicked()
{
    timer.start(1000);
}


void MainWindow::on_timer()
{
    if(timer.isActive()) return;
    ttime--;
    (display LCD values)
    if(ttime<=0) 
    {
        ttime=0;
        (emit signal for alarm or whatever you want)
        timer.stop();
    }
}

void MainWindow::on_tpause_clicked()
{
    timer.stop();
    (display LCD values)
}

void MainWindow::on_treset_clicked()
{
    timer.stop();
    ttime=0;
    (display zeroes)
}
0

(Posted on behalf of the OP).

Everything is solved! I was resetting the stopwatch display by accident. Thanks @Michael!

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // ttimer was declared in "MainWindow" -> QTimer ttimer;
    connect(&ttimer, SIGNAL(timeout()), this, SLOT(on_timer()));
}
void MainWindow::on_tstart_clicked()
{
    ttime = ttime == 0 ? (ui->hr->value() * 3600 + ui->min->value() * 60 + ui->sec->value()) : ttime;
    ttimer.start(1000);
}

void MainWindow::on_timer()
{
    if (!ttimer.isActive()) return;
    --ttime;
    const unsigned short hr = ttime / 3600, min = ttime % 3600 / 60, sec = ttime % 60;
    ui->tsec2->display(sec % 10);
    ui->tsec1->display(sec / 10);
    ui->tmin2->display(min % 10);
    ui->tmin1->display(min / 10);
    ui->thr2->display(hr % 10);
    ui->thr1->display(hr / 10);
    if (ttime <= 0)
    {
        // (emit signal for alarm or whatever you want)
        ttimer.stop();
    }
}

void MainWindow::on_tpause_clicked()
{
    ttimer.stop();
    // (display LCD values)
}

void MainWindow::on_treset_clicked()
{
    ttimer.stop();
    ttime = 0;
    ui->tsec2->display(0);
    ui->tsec1->display(0);
    ui->tmin2->display(0);
    ui->tmin1->display(0);
    ui->thr2->display(0);
    ui->thr1->display(0);
}
halfer
  • 19,824
  • 17
  • 99
  • 186
0

I implemented QTimer in my code, but when I press the "Start" button (on_tstart_clicked) or any other buttons, nothing happens (no change in display).

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // ttimer was declared in "MainWindow" -> QTimer ttimer;
    connect(&ttimer, SIGNAL(timeout()), this, SLOT(on_timer()));
}
void MainWindow::on_tstart_clicked()
{
    ttime = ttime == 0 ? (ui->hr->value() * 3600 + ui->min->value() * 60 + ui->sec->value()) : ttime;
    ttimer.start(1000);
}

void MainWindow::on_timer()
{
    if (!ttimer.isActive()) return;
    --ttime;
    const unsigned short hr = ttime / 3600, min = ttime % 3600 / 60, sec = ttime % 60;
    ui->tsec2->display(sec % 10);
    ui->tsec1->display(sec / 10);
    ui->tmin2->display(min % 10);
    ui->tmin1->display(min / 10);
    ui->thr2->display(hr % 10);
    ui->thr1->display(hr / 10);
    if (ttime <= 0)
    {
        // (emit signal for alarm or whatever you want)
        ttimer.stop();
    }
}

void MainWindow::on_tpause_clicked()
{
    ttimer.stop();
    // (display LCD values)
}

void MainWindow::on_treset_clicked()
{
    ttimer.stop();
    ttime = 0;
    ui->ssec2>tsec2->display(0);
    ui->ssec1>tsec1->display(0);
    ui->smin2>tmin2->display(0);
    ui->smin1>tmin1->display(0);
    ui->shr2>thr2->display(0);
    ui->shr1>thr1->display(0);
}

The issue was simple, but I kept glossing over it. I had to change ttimer.isActive() to !ttimer.isActive().

But, now the the reset (on_treset_clicked) doesn't work. The QLCDNumber's aren't reset to 0.

cppxor2arr
  • 295
  • 2
  • 12