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

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

How to slow down printing progress values on a label?

问题

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

for (i = 0; i <= 100; i++)
{
    data = QString::number(i);
    ui->label_29->setText(data + "%");
}

我尝试使用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:

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

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

// 使用Qt的QTimer类在每个步骤之间设置延迟以更新进度条,而不会冻结GUI。

class ProgressBarExample : public QObject
{
    Q_OBJECT

public:
    ProgressBarExample() : i(0)
    {
        // 创建并配置标签
        label = new QLabel();
        label->setAlignment(Qt::AlignCenter);
        label->setFixedSize(200, 30);

        // 创建QTimer对象并将其超时信号连接到updateProgressBar槽
        timer = new QTimer(this);
        connect(timer, &QTimer::timeout, this, &ProgressBarExample::updateProgressBar);

        // 设置更新之间的所需间隔(以毫秒为单位)
        int interval = 100; // 根据您的需求调整此值
        timer->setInterval(interval);

        // 启动定时器
        timer->start();

        // 显示标签
        label->show();
    }

private slots:
    void updateProgressBar()
    {
        if (i > 100) {
            // 如果进度达到100%,则停止定时器
            timer->stop();
            return;
        }

        QString data = QString::number(i);
        label->setText(data + "%");

        i++; // 增加计数器
    }

private:
    QLabel* label;
    QTimer* timer;
    int i;
};

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    ProgressBarExample example;

    return app.exec();
}
英文:

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:

#include &lt;QApplication&gt;
#include &lt;QLabel&gt;
#include &lt;QTimer&gt;

class ProgressBarExample : public QObject
{
    Q_OBJECT

public:
    ProgressBarExample() : i(0)
    {
        // Create and configure the label
        label = new QLabel();
        label-&gt;setAlignment(Qt::AlignCenter);
        label-&gt;setFixedSize(200, 30);

        // Create the QTimer object and connect its timeout signal to the updateProgressBar slot
        timer = new QTimer(this);
        connect(timer, &amp;QTimer::timeout, this, &amp;ProgressBarExample::updateProgressBar);

        // Set the desired interval (in milliseconds) between updates
        int interval = 100; // Adjust this value as per your requirement
        timer-&gt;setInterval(interval);

        // Start the timer
        timer-&gt;start();

        // Show the label
        label-&gt;show();
    }

private slots:
    void updateProgressBar()
    {
        if (i &gt; 100) {
            // Stop the timer if the progress reaches 100%
            timer-&gt;stop();
            return;
        }

        QString data = QString::number(i);
        label-&gt;setText(data + &quot;%&quot;);

        i++; // Increment the counter
    }

private:
    QLabel* label;
    QTimer* timer;
    int i;
};

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    ProgressBarExample example;

    return app.exec();
}

#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 来停止它。

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

#include &lt;QApplication&gt;
#include &lt;QTimer&gt;
#include &lt;QLabel&gt;

int main(int argc,char*argv[])
{
    QApplication a(argc, argv);

    QLabel *l = new QLabel();
    l-&gt;setText("0");
    l-&gt;setAlignment(Qt::AlignCenter);

    QTimer *t = new QTimer();

    t-&gt;connect(t,&amp;QTimer::timeout,[=]()
    {
        l-&gt;setText(QString::number((l-&gt;text().toInt()+1)%100));
    });

    t-&gt;start(100);

    l-&gt;show();

    return a.exec();
}

这是它的外观:

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

解决方案2:

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

#include &lt;QApplication&gt;
#include &lt;QProgressBar&gt;
#include &lt;QTimer&gt;

int main(int argc,char*argv[])
{
    QApplication a(argc, argv);

    QProgressBar *p = new QProgressBar();

    p-&gt;setRange(0,100);

    p-&gt;setValue(0);

    p-&gt;setOrientation(Qt::Horizontal);

    QTimer *t = new QTimer();

    t-&gt;connect(t,&amp;QTimer::timeout,[=]()
    {
        p-&gt;setValue((p-&gt;value()+1)%p-&gt;maximum());
    });

    t-&gt;start(100);

    p-&gt;show();

    return a.exec();
}

这是它的外观:

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

英文:

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:

#include &lt;QApplication&gt;
#include &lt;QTimer&gt;
#include &lt;QLabel&gt;


int main(int argc,char*argv[])
{
    QApplication a(argc, argv);

    QLabel *l = new QLabel();
    l-&gt;setText(&quot;0&quot;);
    l-&gt;setAlignment(Qt::AlignCenter);

    QTimer *t = new QTimer();

    t-&gt;connect(t,&amp;QTimer::timeout,[=]()
    {
        l-&gt;setText(QString::number((l-&gt;text().toInt()+1)%100));
    });

    t-&gt;start(100);

    l-&gt;show();

    return a.exec();
}

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:

#include &lt;QApplication&gt;
#include &lt;QProgressBar&gt;
#include &lt;QTimer&gt;

int main(int argc,char*argv[])
{
    QApplication a(argc, argv);

    QProgressBar *p = new QProgressBar();

    p-&gt;setRange(0,100);

    p-&gt;setValue(0);

    p-&gt;setOrientation(Qt::Horizontal);

    QTimer *t = new QTimer();

    t-&gt;connect(t,&amp;QTimer::timeout,[=]()
    {
        p-&gt;setValue((p-&gt;value()+1)%p-&gt;maximum());
    });

    t-&gt;start(100);

    p-&gt;show();

    return a.exec();
}

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:

确定