QProgressBar没有显示进度?

时间:2010-05-10 21:22:16

标签: multithreading user-interface qt

我在更新进度条时的第一个天真就是在我的循环中包含以下几行,正在进行处理,制作如下:

while(data.hasMoreItems())
{
    doSomeProcessing(data.nextItem())

    //Added these lines but they don't do anything
    ui->progressBar->setValue(numberProcessed++);
    ui->progressBar->repaint();
}

我认为添加repaint()会在更新GUI时暂停执行,但显然并非如此简单。看完问题之后:

QProgressBar Error
Progress bar is not showing progress

看起来我将不得不将数据处理放在不同的线程中,然后将来自数据处理线程的信号连接到GUI线程以更新进度条。我对GUI和线程缺乏经验,我想知道是否有人能指出我正确的方向,即我应该使用什么Qt类来实现。我猜我需要一个QThread对象,但我一直在查看QProgressBar文档,但它没有提出线程主题。

3 个答案:

答案 0 :(得分:11)

正如@rjh和@Georg指出的那样,基本上有两种不同的选择:

  1. 使用QApplication::processEvents(),或
  2. 强制处理事件
  3. 创建一个thread,发出可用于更新进度条的信号
  4. 如果您正在进行任何非平凡的处理,我建议将处理移至线程。

    关于线程最重要的事情是除了主GUI线程(你没有开始也没有创建),你永远不能直接从线程中更新GUI 。< / p>

    QObject::connect()的最后一个参数是Qt::ConnectionType枚举,默认情况下会考虑是否涉及线程。

    因此,您应该能够创建一个执行处理的QThread的简单子类:

    class DataProcessingThread : public QThread
     {
    
     public:
         void run();
     signals:
         void percentageComplete(int);
     };
    
     void MyThread::run()
     {
        while(data.hasMoreItems())
        {
          doSomeProcessing(data.nextItem())
          emit percentageCompleted(computePercentageCompleted());
        }
     }
    

    然后在GUI代码中的某处:

    DataProcessingThread dataProcessor(/*data*/);
    connect(dataProcessor, SIGNAL(percentageCompleted(int)), progressBar, SLOT(setValue(int));
    dataProcessor.start();
    

答案 1 :(得分:3)

您需要在处理循环内定期调用QApplication::processEvents()以让它处理UI事件。

正如乔治所说,Qt是一个单线程的合作多任务环境。您可以完全控制您的进程,直到您使用processEvents()自愿放弃它 - 直到您这样做,Qt无法更新UI元素,处理异步HTTP请求,处理输入或其他任何事情。当你处于漫长的处理循环中时,你应该确保这些东西能够获得时间片。

答案 2 :(得分:2)

您可以创建一个发出信号QThread的{​​{1}}子类,并将其连接到progressChanged

默认情况下,

QProgressBar会建立连接connect()。这意味着信号槽机制已经为您解决了线程问题,因此您无需担心这一点。