如何减缓标签上打印进度值的显示速度?

huangapple go评论155阅读模式
英文:

How to slow down printing progress values on a label?

问题

我正在使用一个标签来在Qt C++中作为进度条的一部分打印0到100。我使用下面的代码来实现,但它执行得太快了:

  1. for (i = 0; i <= 100; i++)
  2. {
  3. data = QString::number(i);
  4. ui->label_29->setText(data + "%");
  5. }

我尝试使用sleep()函数,但它会冻结exe文件,无法运行。我在考虑使用线程,但我不知道如何做。

英文:

I'm using a label to print 0 to 100 as a part of an progress bar in Qt C++. I use the code below to do it but it executes too fast:

  1. for (i = 0; i &lt;= 100; i++)
  2. {
  3. data = QString::number(i);
  4. ui-&gt;label_29-&gt;setText(data + &quot;%&quot;);
  5. }

I tried to use sleep() function but it froze the exe file and it couldn't run. I'm thinking of using a thread but I don't know how.

答案1

得分: 6

  1. // 使用Qt的QTimer类在每个步骤之间设置延迟以更新进度条,而不会冻结GUI。
  2. class ProgressBarExample : public QObject
  3. {
  4. Q_OBJECT
  5. public:
  6. ProgressBarExample() : i(0)
  7. {
  8. // 创建并配置标签
  9. label = new QLabel();
  10. label->setAlignment(Qt::AlignCenter);
  11. label->setFixedSize(200, 30);
  12. // 创建QTimer对象并将其超时信号连接到updateProgressBar槽
  13. timer = new QTimer(this);
  14. connect(timer, &QTimer::timeout, this, &ProgressBarExample::updateProgressBar);
  15. // 设置更新之间的所需间隔(以毫秒为单位)
  16. int interval = 100; // 根据您的需求调整此值
  17. timer->setInterval(interval);
  18. // 启动定时器
  19. timer->start();
  20. // 显示标签
  21. label->show();
  22. }
  23. private slots:
  24. void updateProgressBar()
  25. {
  26. if (i > 100) {
  27. // 如果进度达到100%,则停止定时器
  28. timer->stop();
  29. return;
  30. }
  31. QString data = QString::number(i);
  32. label->setText(data + "%");
  33. i++; // 增加计数器
  34. }
  35. private:
  36. QLabel* label;
  37. QTimer* timer;
  38. int i;
  39. };
  40. int main(int argc, char *argv[])
  41. {
  42. QApplication app(argc, argv);
  43. ProgressBarExample example;
  44. return app.exec();
  45. }
英文:

To update the progress bar with a delay between each step without freezing the GUI, you can utilize Qt's QTimer class to schedule the updates at regular intervals.

Here's an example:

  1. #include &lt;QApplication&gt;
  2. #include &lt;QLabel&gt;
  3. #include &lt;QTimer&gt;
  4. class ProgressBarExample : public QObject
  5. {
  6. Q_OBJECT
  7. public:
  8. ProgressBarExample() : i(0)
  9. {
  10. // Create and configure the label
  11. label = new QLabel();
  12. label-&gt;setAlignment(Qt::AlignCenter);
  13. label-&gt;setFixedSize(200, 30);
  14. // Create the QTimer object and connect its timeout signal to the updateProgressBar slot
  15. timer = new QTimer(this);
  16. connect(timer, &amp;QTimer::timeout, this, &amp;ProgressBarExample::updateProgressBar);
  17. // Set the desired interval (in milliseconds) between updates
  18. int interval = 100; // Adjust this value as per your requirement
  19. timer-&gt;setInterval(interval);
  20. // Start the timer
  21. timer-&gt;start();
  22. // Show the label
  23. label-&gt;show();
  24. }
  25. private slots:
  26. void updateProgressBar()
  27. {
  28. if (i &gt; 100) {
  29. // Stop the timer if the progress reaches 100%
  30. timer-&gt;stop();
  31. return;
  32. }
  33. QString data = QString::number(i);
  34. label-&gt;setText(data + &quot;%&quot;);
  35. i++; // Increment the counter
  36. }
  37. private:
  38. QLabel* label;
  39. QTimer* timer;
  40. int i;
  41. };
  42. int main(int argc, char *argv[])
  43. {
  44. QApplication app(argc, argv);
  45. ProgressBarExample example;
  46. return app.exec();
  47. }
  48. #include &quot;main.moc&quot;

答案2

得分: 0

从Qt文档的QThread部分:

管理线程

>注意:通常情况下,wait()sleep() 函数应该是不必要的,因为Qt是一个事件驱动的框架。可以考虑使用 finished() 信号来代替 wait()。可以考虑使用 QTimer 来代替 sleep() 函数。

QThread::sleep
>如果需要等待特定条件发生,请避免使用此函数。相反,连接一个槽到指示变化的信号,或者使用事件处理程序...

而且,由于您的目标是:

>我正在使用标签来打印0到100作为进度条的一部分

以下是实现这一目标的两种方法:

解决方案1:

您可以使用 QLabel 模仿进度条,并通过使用 QTimer 将其连接到一个 lambda 函数,该函数会增加标签上显示的值,从而使进度可见。我使用了 100ms 的超时,我正在循环进行进度,您可以在某个条件下使用 QTimer::stop 来停止它。

这是一个最小化的可复现示例:

  1. #include &lt;QApplication&gt;
  2. #include &lt;QTimer&gt;
  3. #include &lt;QLabel&gt;
  4. int main(int argc,char*argv[])
  5. {
  6. QApplication a(argc, argv);
  7. QLabel *l = new QLabel();
  8. l-&gt;setText("0");
  9. l-&gt;setAlignment(Qt::AlignCenter);
  10. QTimer *t = new QTimer();
  11. t-&gt;connect(t,&amp;QTimer::timeout,[=]()
  12. {
  13. l-&gt;setText(QString::number((l-&gt;text().toInt()+1)%100));
  14. });
  15. t-&gt;start(100);
  16. l-&gt;show();
  17. return a.exec();
  18. }

这是它的外观:

如何减缓标签上打印进度值的显示速度?

解决方案2:

要显示进度,Qt 提供了 QProgressBar,以下是如何在上述解决方案中使用它的方法:

  1. #include &lt;QApplication&gt;
  2. #include &lt;QProgressBar&gt;
  3. #include &lt;QTimer&gt;
  4. int main(int argc,char*argv[])
  5. {
  6. QApplication a(argc, argv);
  7. QProgressBar *p = new QProgressBar();
  8. p-&gt;setRange(0,100);
  9. p-&gt;setValue(0);
  10. p-&gt;setOrientation(Qt::Horizontal);
  11. QTimer *t = new QTimer();
  12. t-&gt;connect(t,&amp;QTimer::timeout,[=]()
  13. {
  14. p-&gt;setValue((p-&gt;value()+1)%p-&gt;maximum());
  15. });
  16. t-&gt;start(100);
  17. p-&gt;show();
  18. return a.exec();
  19. }

这是它的外观:

如何减缓标签上打印进度值的显示速度?

英文:

From Qt documentation of QThread:

Managing Threads

>Note: wait() and the sleep() functions should be unnecessary in general, since Qt is an event-driven framework. Instead of wait(), consider listening for the finished() signal. Instead of the sleep() functions, consider using QTimer.

QThread::sleep:
>Avoid using this function if you need to wait for a given condition to change. Instead, connect a slot to the signal that indicates the change or use an event handler...

And since your goal is:

>I'm using a label to print 0 to 100 as a part of a progress bar

Here are 2 ways you can achieve that:

Solution 1:

You can use a QLabel to mimic a progress bar, and make it possible to see it progressing, by using a QTimer, connecting its timeout signal to a lambda that incrementing the value displayed on the label itself.

I used a timeout of 100ms, and I'm looping the progress, you can tweak that to make it stop at a 100 by using QTimer::stop at some condition.

Here's a minimal reproducible example:

  1. #include &lt;QApplication&gt;
  2. #include &lt;QTimer&gt;
  3. #include &lt;QLabel&gt;
  4. int main(int argc,char*argv[])
  5. {
  6. QApplication a(argc, argv);
  7. QLabel *l = new QLabel();
  8. l-&gt;setText(&quot;0&quot;);
  9. l-&gt;setAlignment(Qt::AlignCenter);
  10. QTimer *t = new QTimer();
  11. t-&gt;connect(t,&amp;QTimer::timeout,[=]()
  12. {
  13. l-&gt;setText(QString::number((l-&gt;text().toInt()+1)%100));
  14. });
  15. t-&gt;start(100);
  16. l-&gt;show();
  17. return a.exec();
  18. }

Here's how it looks:

如何减缓标签上打印进度值的显示速度?

Solution 2:

To display a progress, Qt offers QProgressBar, here's how you can use it in the above solution:

  1. #include &lt;QApplication&gt;
  2. #include &lt;QProgressBar&gt;
  3. #include &lt;QTimer&gt;
  4. int main(int argc,char*argv[])
  5. {
  6. QApplication a(argc, argv);
  7. QProgressBar *p = new QProgressBar();
  8. p-&gt;setRange(0,100);
  9. p-&gt;setValue(0);
  10. p-&gt;setOrientation(Qt::Horizontal);
  11. QTimer *t = new QTimer();
  12. t-&gt;connect(t,&amp;QTimer::timeout,[=]()
  13. {
  14. p-&gt;setValue((p-&gt;value()+1)%p-&gt;maximum());
  15. });
  16. t-&gt;start(100);
  17. p-&gt;show();
  18. return a.exec();
  19. }

Here's how it looks:

如何减缓标签上打印进度值的显示速度?

huangapple
  • 本文由 发表于 2023年6月5日 11:03:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76403278.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定