在进度监控和更新进度条的上下文中

Posted

技术标签:

【中文标题】在进度监控和更新进度条的上下文中【英文标题】:In the context of progress monitoring and updating a progress bar 【发布时间】:2021-09-15 14:47:09 【问题描述】:

。可以启动一个计时器并每隔几秒钟更新一次进度条。我们测量完成任务所需的时间并硬编码所需的秒数。它有点工作,除非即完成任务所需的时间不是恒定的。此外,如果任务的实现发生变化,变得更慢/更快,那么任务可能会在任务栏打开时完成,即 10%,这看起来不太好。

如果时间不是恒定的,还有另一种方法。让我们对doSomething 说,我们跨越了几个航路点,在这些航路点上我们发出信号来报告进度。 我们传入航点的总数(即 3 个),并在每个航点上计算比率。

但是,如果我们添加/删除航点,我们必须调整调用,而不是 doSomething(3),它可能是 doSomething(5)。除非我们找到一种在编译时自动更新int total = 3 的方法,否则这可能吗?也许预处理器宏?我可以计算在编译时我调用process() 的次数吗?

小部件.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;
    
;

任务.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);
;

上面的输出是:

 - progress 33.3333
 - progress 66.6667
 - progress 100

但如果我们取消注释其中一个对progress() 的调用,它会输出:

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

这是我想要避免的。

【问题讨论】:

您的问题似乎有点开放式。您希望我们回答的具体内容是什么?听起来您的问题是:“计算进度的最佳方法是什么?”人们可能会提出不同的想法,但有没有事实上正确的方法? 哦,不是这样的。是否可以在编译时计算函数(progress())被调用的次数?然后自动更新int total = 3;? 一个好的做法是根据领域问题固有的一些数量来定义进度。示例:与文件大小相比传输的字节数。如果它只能通过所采取的一些行动来衡量,或许可以定义一个描述具体行动类型的枚举类,并强制每个调用者识别刚刚采取的行动。这使得它更难搞砸,如果你这样做的话,退化也不会那么严重。 【参考方案1】:

我的建议是改变你的方法。不要试图计算函数调用。相反,以隐式计算总数的方式构建您的进度步骤。就像将它们存储在向量中一样。

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);

【讨论】:

有趣。然而,这可能会导致一些严重的重构,因为这里的代码分布在一系列类中。 我喜欢在数据结构中明确包含函数 (lambda) 作为问题解决模型的一部分。步骤执行与进度计算紧密结合。

以上是关于在进度监控和更新进度条的上下文中的主要内容,如果未能解决你的问题,请参考以下文章

mfc编写一个flash播放器slider进度条的程序,在新建线程中,怎么实现进度条的更新

Android更新带进度条的通知栏

Android更新带进度条的通知栏

vc6.0里MFC进度条如何使用

c#如何根据文件数量控制进度条

异步任务的进度对话框