英文:
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 <= 100; i++)
{
data = QString::number(i);
ui->label_29->setText(data + "%");
}
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 <QApplication>
#include <QLabel>
#include <QTimer>
class ProgressBarExample : public QObject
{
Q_OBJECT
public:
ProgressBarExample() : i(0)
{
// Create and configure the label
label = new QLabel();
label->setAlignment(Qt::AlignCenter);
label->setFixedSize(200, 30);
// Create the QTimer object and connect its timeout signal to the updateProgressBar slot
timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &ProgressBarExample::updateProgressBar);
// Set the desired interval (in milliseconds) between updates
int interval = 100; // Adjust this value as per your requirement
timer->setInterval(interval);
// Start the timer
timer->start();
// Show the label
label->show();
}
private slots:
void updateProgressBar()
{
if (i > 100) {
// Stop the timer if the progress reaches 100%
timer->stop();
return;
}
QString data = QString::number(i);
label->setText(data + "%");
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 "main.moc"
答案2
得分: 0
从Qt文档的QThread部分:
>注意:通常情况下,wait()
和 sleep()
函数应该是不必要的,因为Qt是一个事件驱动的框架。可以考虑使用 finished()
信号来代替 wait()
。可以考虑使用 QTimer
来代替 sleep()
函数。
QThread::sleep:
>如果需要等待特定条件发生,请避免使用此函数。相反,连接一个槽到指示变化的信号,或者使用事件处理程序...
而且,由于您的目标是:
>我正在使用标签来打印0到100作为进度条的一部分
以下是实现这一目标的两种方法:
解决方案1:
您可以使用 QLabel
模仿进度条,并通过使用 QTimer
将其连接到一个 lambda 函数,该函数会增加标签上显示的值,从而使进度可见。我使用了 100ms
的超时,我正在循环进行进度,您可以在某个条件下使用 QTimer::stop 来停止它。
这是一个最小化的可复现示例:
#include <QApplication>
#include <QTimer>
#include <QLabel>
int main(int argc,char*argv[])
{
QApplication a(argc, argv);
QLabel *l = new QLabel();
l->setText("0");
l->setAlignment(Qt::AlignCenter);
QTimer *t = new QTimer();
t->connect(t,&QTimer::timeout,[=]()
{
l->setText(QString::number((l->text().toInt()+1)%100));
});
t->start(100);
l->show();
return a.exec();
}
这是它的外观:
解决方案2:
要显示进度,Qt 提供了 QProgressBar,以下是如何在上述解决方案中使用它的方法:
#include <QApplication>
#include <QProgressBar>
#include <QTimer>
int main(int argc,char*argv[])
{
QApplication a(argc, argv);
QProgressBar *p = new QProgressBar();
p->setRange(0,100);
p->setValue(0);
p->setOrientation(Qt::Horizontal);
QTimer *t = new QTimer();
t->connect(t,&QTimer::timeout,[=]()
{
p->setValue((p->value()+1)%p->maximum());
});
t->start(100);
p->show();
return a.exec();
}
这是它的外观:
英文:
From Qt documentation of QThread:
>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 <QApplication>
#include <QTimer>
#include <QLabel>
int main(int argc,char*argv[])
{
QApplication a(argc, argv);
QLabel *l = new QLabel();
l->setText("0");
l->setAlignment(Qt::AlignCenter);
QTimer *t = new QTimer();
t->connect(t,&QTimer::timeout,[=]()
{
l->setText(QString::number((l->text().toInt()+1)%100));
});
t->start(100);
l->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 <QApplication>
#include <QProgressBar>
#include <QTimer>
int main(int argc,char*argv[])
{
QApplication a(argc, argv);
QProgressBar *p = new QProgressBar();
p->setRange(0,100);
p->setValue(0);
p->setOrientation(Qt::Horizontal);
QTimer *t = new QTimer();
t->connect(t,&QTimer::timeout,[=]()
{
p->setValue((p->value()+1)%p->maximum());
});
t->start(100);
p->show();
return a.exec();
}
Here's how it looks:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论