在进度监控和更新进度条的上下文中
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) 作为问题解决模型的一部分。步骤执行与进度计算紧密结合。以上是关于在进度监控和更新进度条的上下文中的主要内容,如果未能解决你的问题,请参考以下文章