Multithreading QProgressBar不显示进度?

Multithreading QProgressBar不显示进度?,multithreading,user-interface,qt,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(

我更新进度条的第一个天真想法是在我的循环中包含以下行,这是在进行处理,这样做:

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

    //Added these lines but they don't do anything
    ui->progressBar->setValue(numberProcessed++);
    ui->progressBar->repaint();
}
我认为添加
repaint()
会在更新GUI时暂停执行,但显然不是那么简单。在看了这些问题之后:



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

您可以创建
QThread
的子类,它发出一个信号
progressChanged
,您可以将该信号连接到
QProgressBar


connect()
根据默认设置进行连接。这意味着信号槽机制已经为您解决了线程问题,因此您不必担心这一点。

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


正如Georg所说,Qt是一个单线程协作多任务环境。在使用processEvents()自动放弃流程之前,您可以完全控制流程-在此之前,Qt无法更新UI元素、处理异步HTTP请求、处理输入或其他任何内容。当您处于一个长的处理循环中时,您需要确保东西得到一个时间片。

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

  • 使用或强制处理事件
  • 创建一个可发出可用于更新进度条的信号的
  • 如果您正在执行任何非平凡的处理,我建议将处理移动到线程

    了解线程最重要的一点是,除了主GUI线程(您不启动也不创建)之外,您永远不能直接从线程中更新GUI

    的最后一个参数是枚举,默认情况下会考虑是否涉及线程

    因此,您应该能够创建执行以下处理的
    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();