Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
841 views
in Technique[技术] by (71.8m points)

multithreading - QProgressBar not showing progress?

My first naive at updating my progress bar was to include the following lines in my loop which is doing the processing, making something like this:

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

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

I thought adding the repaint() would make the execution pause while it updated the GUI, but apparently it's not that simple. After looking at the questions:

QProgressBar Error
Progress bar is not showing progress

it looks like I'm going to have to put the data processing in a different thread and then connect a signal from the data processing thread to the GUI thread to update the progressbar. I'm rather inexperienced with GUIs and threads and I was wondering if anyone could just point me in the right direction, ie what Qt classes should I be looking at using for this. I'd guess I need a QThread object but I've been looking through the QProgressBar documentation but it doesn't bring up the topic of threading.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As @rjh and @Georg have pointed out, there are essentially two different options:

  1. Force processing of events using QApplication::processEvents(), OR
  2. Create a thread that emits signals that can be used to update the progress bar

If you're doing any non-trivial processing, I'd recommend moving the processing to a thread.

The most important thing to know about threads is that except for the main GUI thread (which you don't start nor create), you can never update the GUI directly from within a thread.

The last parameter of QObject::connect() is a Qt::ConnectionType enum that by default takes into consideration whether threads are involved.

Thus, you should be able to create a simple subclass of QThread that does the processing:

class DataProcessingThread : public QThread
 {

 public:
     void run();
 signals:
     void percentageComplete(int);
 };

 void MyThread::run()
 {
    while(data.hasMoreItems())
    {
      doSomeProcessing(data.nextItem())
      emit percentageCompleted(computePercentageCompleted());
    }
 }

And then somewhere in your GUI code:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...