代码之家  ›  专栏  ›  技术社区  ›  Graphics Noob

qprogressbar没有显示进度?

  •  8
  • Graphics Noob  · 技术社区  · 14 年前

    我在更新进度条时的第一个幼稚之处是在循环中包含以下行,这些行正在进行处理,并生成类似的结果:

    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 回复  |  直到 6 年前
        1
  •  11
  •   feedc0de RushPL    6 年前

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

    1. 使用强制处理事件 QApplication::processEvents()
    2. 创建一个 thread 发出可用于更新进度条的信号

    如果您正在进行任何非常重要的处理,我建议您将处理移到一个线程。

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

    的最后一个参数 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();
    
        2
  •  3
  •   rjh    14 年前

    你需要打电话 QApplication::processEvents() 在您的处理循环中周期性地让它处理UI事件。

    正如Georg所说,qt是一个单线程协作的多任务环境。在使用processEvents()自愿放弃之前,您可以完全控制您的流程-在这样做之前,qt不能更新UI元素、处理异步HTTP请求、处理输入或几乎任何其他内容。当你处于一个长的处理循环中时,要确保这些东西得到一个时间片,这取决于你自己。

        3
  •  2
  •   Georg Fritzsche    14 年前

    可以创建的子类 QThread 发出信号 progressChanged ,连接到 QProgressBar .

    connect() 建立连接 auto connections 默认情况下。这意味着信号槽机制已经为您解决了线程问题,所以您不需要担心这个问题。