KcFnMi
KcFnMi

Reputation: 6171

In the context of progress monitoring and updating a progress bar

In the context of progress monitoring and updating a progress bar. One could start a timer and update the progress bar every i.e. couple of seconds. We measure the time it takes to complete the task and hard code the number of seconds it takes. And it kinda works, unless i.e. the time task takes to complete is not constant. Also, if the implementation of the task change, becoming slower/faster, then task might complete when task bar is on i.e. 10% which wont look great.

If time is not constant there is another approach. Let's say to doSomething we cross over a couple of waypoints in which we emit a signal to report the progress. We pass in the total number of waypoints (i.e. 3) and on every waypoint we compute the ratio.

However if we add/remove waypoints we have to adjust the call, instead of doSomething(3) it might be i.e. doSomething(5). Unless we find a way to update that int total = 3 at compile time automatically, would that be possible? Perhaps preprocessor macros? Can I count the number of times I call process() at compile time?

widget.h

class Widget : public QWidget
{
    Q_OBJECT

    Task m_task;

public:
    Widget(QWidget *parent = nullptr)
    {
        connect(&m_task, &Task::status, this, &Widget::showProgrss);
    
        int total = 3;
        m_task.doSomething(total);
    }

public slots:
    void showProgrss(float p)
    {
        qDebug() << " - progress" << p;
    }
};

task.h

class Task : public QObject
{
    Q_OBJECT

    float m_total= 0;
    int count = 0;

public:
    explicit Task(QObject *parent = nullptr){}

    void doSomething(int t)
    {
        m_total = t;
        progress();
        func1();
        progress();
        func2();
        progress();
    }

private:
    void progress()
    {
        float p = (++count/m_total)*100;
        emit status(p);
    }

    void func1()
    {
//        progress();
    }

    void func2()
    {
//        progress();
    }

signals:
    void status(float p);
};

With the above, output was:

 - progress 33.3333
 - progress 66.6667
 - progress 100

But if we uncomment one of those calls to progress(), it outputs:

 - progress 33.3333
 - progress 66.6667
 - progress 100
 - progress 133.333

Which is what I'm trying to avoid.

Upvotes: 0

Views: 321

Answers (1)

JarMan
JarMan

Reputation: 8277

My recommendation is to change your approach. Don't try to count function calls. Instead, structure your progress steps in a way that the total is implicitly counted for you. Like storing them in a vector.

std::vector<std::function<void()>> m_steps {
    step1,
    step2,
    step3
}

void doSomething() 
{
    for (auto &f : m_steps) {
        f();
        progress();
    }
}

void progress()
{
    float p = (++count/m_steps.size())*100;
    emit status(p);
}

Upvotes: 1

Related Questions