在 QProgressBar 中显示进度

Posted

技术标签:

【中文标题】在 QProgressBar 中显示进度【英文标题】:Display progress in QProgressBar 【发布时间】:2019-02-26 10:43:24 【问题描述】:

我正在使用QProgress来显示读取配置文件的状态。我有一个类向主窗口发出信号以显示状态。目前,我可以显示状态,但它立即显示 100%,我希望它更可靠。就像我可以看到它从 0 到 5 到 20 到 45 等等,直到它达到 100%。这是我到目前为止吃过的东西:

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new 
Ui::MainWindow)

    connect(sampleClass, SIGNAL(onDisplayStatus(int)), this, 
    SLOT(onDisplayStatus(int)));

    // OtherClass instance
    // config file has lots of fields to be read
    otherClass->validateConfigfile();


MainWindow::onDisplayStatus(int status)

    ui->ProgressStatus.setValue(status);


SampleClass::displayStatus(int value)

    emit onDisplayStatus(value);


// This will validate if the config file is valid or existing; the 
// progress will be set to 10 if valid and existing
OtherClass::validateConfigfile() 

    // instance of SampleClass
    //10 is the value of progress. 
    //I dont want it to be fixed. Pleas suggest how to properly compute 
    //the value
    sampleClassInstance->displayStatus(10); 

    loadSection1();
    loadSection2();


OtherClass::loadSection1()

    // load section 1 here
    sampleClassInstance->displayStatus(20);


OtherClass::loadSection2()

    // load section 2 here
    sampleClassInstance->displayStatus(35);

注意:我的配置文件包含许多字段。下面是例子:

[Section 1]
S1Field1 = 0
S1Field2 = 1
S1Field3 = 2

[Section 2]
S2Field1 = 0
S2Field2 = 1

[Section 3]
S3Field1 = 0
S3Field2 = 1
S3Field3 = 2
S3Field4 = 6
S3Field5 = 4
S3Field6 = 9

等等……

我在 OtherClass 中创建了一个方法来读取每个部分和字段。每读完一个部分就会显示进度值,直到进度达到100。

【问题讨论】:

你是在逐行读取文件吗? 是的,我正在逐行读取文件 【参考方案1】:

请看文档:https://doc.qt.io/qt-5/qprogressbar.html

你必须设置进度条的最大值和最小值。

【讨论】:

是的,这是真的。我以为他想要一个定制的。他说当他设置为 10 时它会立即跳到 100%,可能是他设置了错误的范围。 @user123456 请显示更多代码。 我猜想 user123456 实际上需要一个文件读取方法来根据文件大小或类似的东西计算进度。但是这个问题真的不清楚! @BenjaminBihler 是的,你是对的。我实际上需要类似的东西并根据文件大小更新进度条。 @user123456 进度评估独立于使用 QProgressBar 显示进度,因此您的问题有点误导。【参考方案2】:

如果您在主线程(Qt GUI 的线程)中进行处理,您的小部件将在您完成之前不会被更新/重绘,然后直接显示 100%。

为了正确使用进度条,您需要在不同的进程中处理一些代码或一些异步代码。

PS:你也可以直接将你的worker类信号连接到进度条槽,你不需要MainWindow::onDisplayStatus(int status)

【讨论】:

另一个(有点问题但可行的)解决方案是让主线程中的处理例程定期调用qApp->processEvents() @ymoreau 你能给我举个例子吗? 这真的取决于你必须处理什么,IO,计算......有许多不同的异步方式。请记住,您不应该让主线程保持忙碌。 doc.qt.io/qt-5/thread-basics.html 或正如 Jeremy 所说的 doc.qt.io/qt-5/qcoreapplication.html#processEvents 我尝试创建一个简单的 for 循环,只是为了查看进度条是否会增加值。发生的事情是它立即显示 100%。我看不到它在增加。 for(int i = 0; i processEvents(QEventloops::ExcludeUserInputEvents); 【参考方案3】:

您首先必须在读取文件时计算进度。或许Most efficient way of creating a progress bar while reading input from a file 可以帮到你。

然后您必须将进度报告给QProgressBar。为此,您的文件读取方法需要接收进度指示器作为函数参数并调用其状态显示方法。如果您不想显式依赖 Qt,那么您可能需要创建一个纯抽象的ProgressIndicator 接口类,使文件读取方法使用这样的ProgressIndicator,然后创建一个继承自ProgressIndicator 的类和QProgressBar 并将接口方法连接到QProgressBar 中的实现。

【讨论】:

以上是关于在 QProgressBar 中显示进度的主要内容,如果未能解决你的问题,请参考以下文章

QprogressBar怎么显示读取文件进度

QT软件开发之基础控件--2.5.2 QProgressBar进度条

针对类实现 QProgressBar

Qt入门系列开发教程基础控件篇QProgressBar进度条

如何在 QT 中获得具有圆形边缘和圆形进度边缘的 QProgressBar?

QT:QProgressBar 显示文字