March 17, 2012

RazrFalcon RazrFalcon
Lab Rat
125 posts

Can I search for files via QtConcurrent?

 

I need to find files on my HDD (recursively).
But it takes a long of time and GUI freezes.
I try to solve it via QtConcurrent:

  1. void MainWindow::on_buttonSearch_clicked()
  2. {
  3.     connect(&watcher, SIGNAL(finished()), this, SLOT(loadFinished()));
  4.     future = QtConcurrent::run(&MainWindow::searchForFiles, lineEditInDir->text());  // in .h QFuture<QFileInfoList> future;
  5.     watcher.setFuture(future);
  6. }
  7.  
  8. QFileInfoList MainWindow::searchForFiles(const QString &startDir)
  9. {
  10.     QDir dir(startDir);
  11.     QFileInfoList list;
  12.     foreach (QString file, dir.entryList(QStringList("*.svg"), QDir::Files))
  13.         list += QFileInfo(startDir+"/"+file);
  14.     foreach (QString subdir, dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot))
  15.         list += searchForFiles(startDir+"/"+subdir);
  16.     return list;
  17. }
  18.  
  19. void MainWindow::loadFinished()
  20. {
  21.     fileList = future.result();
  22.     qDebug()<<fileList.count();
  23. }

All works fine, I think, but I can’t cancel it. future.cancel() didn’t work, because I use QtConcurrent::run().
And i don’t know how to put files search into QtConcurrent::mapped(), which can be canceled.

 Signature 

QT != Qt
Gentoo + KDE

2 replies

March 19, 2012

Andre Andre
Robot Herder
6417 posts

I think it would be useless to use QtConcurrent for this. QtConcurrent is suitable for problems that are are easy to parallelize. Searching your HDD will have I/O as the bottleneck, so using multiple threads to do that is not efficient. The threads will end up waiting for each other.

So, I would use either a QObject derived worker that you move to a vanilla QThread, or a QRunnable subclass in conjunction with QThreadPool. Because you seem to need cancel capabilities, I think the QThread route would be easiest.

March 19, 2012

Volker Volker
Ant Farmer
5428 posts

Using QtConcurrent can even worse the situation as OS caches might get flushed once the next thread is running and the data needs to be re-read if the first thread is active again.

 
  ‹‹ Destruction in separate threads      How to insert QProgressIndicator into QLineEdit? ››

You must log in to post a reply. Not a member yet? Register here!