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所指出的,基本上有两种不同的选择:
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();