1

我有一个简单的循环,我正在执行不确定长度的操作。我设置了一个 QProgressDialogrange(0,0)来触发其不确定的“忙碌”模式;在我的平台上,这通常会产生一个进度条,其手柄来回弹跳。即使精简到以下内容,对话框也会出现,响应“取消”按钮,但句柄在栏的末端被冻结在适当的位置并且不会循环。

    QProgressDialog* progressDialog =
                     new QProgressDialog("My Progress", "Cancel",
                                         0, 0, this);
    progressDialog->setAttribute(Qt::WA_DeleteOnClose, true);
    progressDialog->setModal(true);
    progressDialog->setMinimumDuration(0);
    progressDialog->show();
    progressDialog->setValue(0);
        
    while (!done)
    {
        QThread::msleep(200);
        QCoreApplication::processEvents();
    }

显然,循环内部实际上发生了更多事情,但无论有没有内容,它的行为都是一样的;注释掉其他所有内容后剩下的内容与描述的一样。

为什么我的进度手柄没有来回弹跳?

4

1 回答 1

0

您的问题不是QProgressDialog问题,而是线程问题。

您正在同一个线程中运行进度条和“作业” - 您的 GUI 线程。我所说的“工作”是指循环内的所有内容,并且被认为是模拟“忙碌”模式,因为在实际情况下它应该需要很长时间。因此,当线程在睡眠时“忙”时,您的 GUI 不会像在同一个线程中那样移动。

您应该使用线程(或 QThread)来启动作业,以允许 GUI 在其自己的 GUI 线程中运行。

这是从“所有”代码(或几乎)复制的示例,并且确实正确显示了忙碌栏。

#include <QApplication>
#include <QProgressDialog>
#include <QThread>

void job()
{
    bool done =true;
    while (!done)
    {
        QThread::msleep(1000);
        QApplication::processEvents();
    }
}

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

    bool done = false;
    QApplication a(argc, argv);
    QProgressDialog* progressDialog = new QProgressDialog("My Progress", "Cancel",

                                         0, 0, nullptr);
    progressDialog->setAttribute(Qt::WA_DeleteOnClose, true);
    progressDialog->setModal(true);
    progressDialog->setMinimumDuration(0);
    progressDialog->show();
    progressDialog->setValue(0);

    QThread* thread = QThread::create(job);
    thread->start();

    return a.exec();
}

这是繁忙栏的结果(它会根据您的需要来回移动)

在此处输入图像描述

于 2021-01-07T14:06:03.467 回答