2010-05-10 190 views
6

我的第一天真的来更新我的进度条是包括在我的循环以下行这是做了处理,使这样的事情:QProgressBar没有显示进度?

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线程更新进度条。我对图形用户界面和线程缺乏经验,我想知道是否有人可以将我指向正确的方向,也就是说我应该使用什么类型的Qt类。我想我需要一个QThread对象,但我一直在查看QProgressBar文档,但它没有提出线程的主题。

回答

9

由于@rjh和@Georg人士指出,主要有两种不同的选择:使用QApplication::processEvents()事件

  1. 部队处理或
  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(); 
1

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

connect()默认情况下使连接auto connections。这意味着信号插槽机制已经为您处理线程问题,所以您不必担心这一点。

3

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

正如Georg所说,Qt是一个单线程协同多任务环境。你可以完全控制你的过程,直到你用processEvents()自动放弃它 - 直到你这样做,Qt不能更新UI元素,处理异步HTTP请求,处理输入或者其他任何东西。当你处于一个长时间的处理循环中时,要确保这些东西获得一个时间片,这取决于你。