// watcher void CoverArtCache::coverLoaded() { QFutureWatcher<FutureResult>* watcher; watcher = reinterpret_cast<QFutureWatcher<FutureResult>*>(sender()); FutureResult res = watcher->result(); if (sDebug) { kLogger.debug() << "coverLoaded" << res.cover; } // Don't cache full size covers (resizedToWidth = 0) // Large cover art wastes space in our cache and will likely // uncache a lot of the small covers we need in the library // table. // Full size covers are used in the Skin Widgets, which are // loaded with an artificial delay anyway and an additional // re-load delay can be accepted. // Create pixmap, GUI thread only QPixmap pixmap = QPixmap::fromImage(res.cover.image); if (!pixmap.isNull() && res.cover.resizedToWidth != 0) { // we have to be sure that res.cover.hash is unique // because insert replaces the images with the same key QString cacheKey = pixmapCacheKey( res.cover.hash, res.cover.resizedToWidth); QPixmapCache::insert(cacheKey, pixmap); } m_runningRequests.remove(qMakePair(res.pRequestor, res.cover.hash)); if (res.signalWhenDone) { emit(coverFound(res.pRequestor, res.cover, pixmap, false)); } }
void Fix8Log::finishedReadingDataFileSlot() { qDebug() << "Finishded future reading.."; QFutureWatcher<FutureReadData *> *watcher = (QFutureWatcher<FutureReadData *> *)sender(); FutureReadData *frd = watcher->result(); }
void executeProgressWatcher(QWidget *parent, const QString& title, Sequence& sequence, MapFunction function) { QProgressDialog progress(parent); { QString t = title; const int num = QThread::idealThreadCount(); if( num > 1 ) { t.append(QObject::tr(" (%1 Threads)").arg(num)); } progress.setWindowTitle(t); } QFutureWatcher<void> watcher; QObject::connect(&watcher, SIGNAL(finished()), &progress, SLOT(reset())); QObject::connect(&watcher, SIGNAL(progressRangeChanged(int, int)), &progress, SLOT(setRange(int, int))); QObject::connect(&watcher, SIGNAL(progressValueChanged(int)), &progress, SLOT(setValue(int))); QObject::connect(&progress, SIGNAL(canceled()), &watcher, SLOT(cancel())); watcher.setFuture(QtConcurrent::map(sequence, function)); progress.exec(); watcher.waitForFinished(); }
void MeshCurvature::ComputePerFace(bool parallel) { Base::Vector3f rkDir0, rkDir1, rkPnt; Base::Vector3f rkNormal; myCurvature.clear(); MeshRefPointToFacets search(myKernel); FacetCurvature face(myKernel, search, myRadius, myMinPoints); if (!parallel) { Base::SequencerLauncher seq("Curvature estimation", mySegment.size()); for (std::vector<unsigned long>::iterator it = mySegment.begin(); it != mySegment.end(); ++it) { CurvatureInfo info = face.Compute(*it); myCurvature.push_back(info); seq.next(); } } else { QFuture<CurvatureInfo> future = QtConcurrent::mapped (mySegment, boost::bind(&FacetCurvature::Compute, &face, _1)); QFutureWatcher<CurvatureInfo> watcher; watcher.setFuture(future); watcher.waitForFinished(); for (QFuture<CurvatureInfo>::const_iterator it = future.begin(); it != future.end(); ++it) { myCurvature.push_back(*it); } } }
void tst_QFutureWatcher::progressValueChanged() { #ifdef PRINT qDebug() << "main thread" << QThread::currentThread(); #endif progressValues.clear(); const int listSize = 20; QList<int> list = createList(listSize); QFutureWatcher<void> futureWatcher; ProgressObject progressObject; QObject::connect(&futureWatcher, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); #ifdef PRINT QObject::connect(&futureWatcher, SIGNAL(progressValueChanged(int)), &progressObject, SLOT(printProgress(int)), Qt::DirectConnection ); #endif QObject::connect(&futureWatcher, SIGNAL(progressValueChanged(int)), &progressObject, SLOT(registerProgress(int))); futureWatcher.setFuture(QtConcurrent::map(list, mapSleeper)); QTestEventLoop::instance().enterLoop(5); QVERIFY(!QTestEventLoop::instance().timeout()); futureWatcher.disconnect(); QVERIFY(progressValues.contains(0)); QVERIFY(progressValues.contains(listSize)); }
http::Response * Server::wait(QFuture<http::Response *> future) { QEventLoop loop; // Interrrupt the event loop when the result is available QFutureWatcher<http::Response *> watcher; watcher.setFuture(future); loop.connect(&watcher, SIGNAL(finished()), SLOT(quit())); // Prevent infinite loop if the future completes before we start the loop QTimer timer; loop.connect(&timer, SIGNAL(timeout()), SLOT(quit())); timer.setSingleShot(false); timer.start(1000); // Process events while waiting so that the UI stays responsive while(!future.isFinished()) { loop.exec(); } http::Response * response = future.result(); if(response->ok()) { m_lastErrorString.clear(); } else if(!response->error().empty()) { m_lastErrorString = toQString(response->error()); } else if(!response->data().empty()) { m_lastErrorString = toQString(response->data()); } else { m_lastErrorString = "HTTP Error " + QString::number(response->status()); } return response; }
void test01(){ // Prepare the vector. QVector<int> vector; for (int i = 0; i < iterations; ++i) vector.append(i); // Create a progress dialog. QProgressDialog dialog; dialog.setLabelText(QString("Progressing using %1 thread(s)...").arg(QThread::idealThreadCount())); // Create a QFutureWatcher and connect signals and slots. QFutureWatcher<void> futureWatcher; QObject::connect(&futureWatcher, SIGNAL(finished()), &dialog, SLOT(reset())); QObject::connect(&dialog, SIGNAL(canceled()), &futureWatcher, SLOT(cancel())); QObject::connect(&futureWatcher, SIGNAL(progressRangeChanged(int,int)), &dialog, SLOT(setRange(int,int))); QObject::connect(&futureWatcher, SIGNAL(progressValueChanged(int)), &dialog, SLOT(setValue(int))); // Start the computation. futureWatcher.setFuture(QtConcurrent::map(vector, spin)); // Display the dialog and start the event loop. dialog.exec(); futureWatcher.waitForFinished(); // Query the future to check if was canceled. qDebug() << "Canceled?" << futureWatcher.future().isCanceled(); }
void CmdSandboxMeshLoaderFuture::activated(int iMsg) { // use current path as default QStringList filter; filter << QObject::tr("All Mesh Files (*.stl *.ast *.bms *.obj)"); filter << QObject::tr("Binary STL (*.stl)"); filter << QObject::tr("ASCII STL (*.ast)"); filter << QObject::tr("Binary Mesh (*.bms)"); filter << QObject::tr("Alias Mesh (*.obj)"); filter << QObject::tr("Inventor V2.1 ascii (*.iv)"); //filter << "Nastran (*.nas *.bdf)"; filter << QObject::tr("All Files (*.*)"); // Allow multi selection QStringList fn = Gui::FileDialog::getOpenFileNames(Gui::getMainWindow(), QObject::tr("Import mesh"), QString(), filter.join(QLatin1String(";;"))); QFuture< Base::Reference<Mesh::MeshObject> > future = QtConcurrent::mapped (fn, loadMesh); QFutureWatcher< Base::Reference<Mesh::MeshObject> > watcher; watcher.setFuture(future); // keep it responsive during computation QEventLoop loop; QObject::connect(&watcher, SIGNAL(finished()), &loop, SLOT(quit())); loop.exec(); App::Document* doc = App::GetApplication().getActiveDocument(); for (QFuture< Base::Reference<Mesh::MeshObject> >::const_iterator it = future.begin(); it != future.end(); ++it) { Mesh::Feature* mesh = static_cast<Mesh::Feature*>(doc->addObject("Mesh::Feature","Mesh")); mesh->Mesh.setValuePtr((Mesh::MeshObject*)(*it)); mesh->purgeTouched(); } }
void AttachDialog::updateProcesses() { QFutureWatcher<ProcDataList> *watcher = new QFutureWatcher<ProcDataList>(this); connect(watcher, SIGNAL(finished()), this, SLOT(updateProcessesFinished())); watcher->setFuture(QtConcurrent::run(processList, m_model->processes())); }
void TrackSelectionDialog::accept() { if (save_on_close_) { SetLoading(tr("Saving tracks") + "..."); // Save tags in the background QFuture<void> future = QtConcurrent::run(&TrackSelectionDialog::SaveData, data_); QFutureWatcher<void>* watcher = new QFutureWatcher<void>(this); watcher->setFuture(future); connect(watcher, SIGNAL(finished()), SLOT(AcceptFinished())); return; } QDialog::accept(); for (const Data& data : data_) { if (data.pending_ || data.results_.isEmpty() || data.selected_result_ == -1) continue; const Song& new_metadata = data.results_[data.selected_result_]; emit SongChosen(data.original_song_, new_metadata); } }
void DocsetRegistry::loadDocset(const QString &path) { QFutureWatcher<Docset *> *watcher = new QFutureWatcher<Docset *>(); connect(watcher, &QFutureWatcher<Docset *>::finished, this, [this, watcher] { QScopedPointer<QFutureWatcher<Docset *>, QScopedPointerDeleteLater> guard(watcher); Docset *docset = watcher->result(); // TODO: Emit error if (!docset->isValid()) { qWarning("Could not load docset from '%s'. Reinstall the docset.", qPrintable(docset->path())); delete docset; return; } docset->setFuzzySearchEnabled(m_fuzzySearchEnabled); const QString name = docset->name(); if (m_docsets.contains(name)) { unloadDocset(name); } m_docsets[name] = docset; emit docsetLoaded(name); }); watcher->setFuture(QtConcurrent::run([path] { return new Docset(path); })); }
int QgsDemHeightMapGenerator::render( int x, int y, int z ) { Q_ASSERT( mJobs.isEmpty() ); // should be always just one active job... // extend the rect by half-pixel on each side? to get the values in "corners" QgsRectangle extent = mTilingScheme.tileToExtent( x, y, z ); float mapUnitsPerPixel = extent.width() / mResolution; extent.grow( mapUnitsPerPixel / 2 ); // but make sure not to go beyond the full extent (returns invalid values) QgsRectangle fullExtent = mTilingScheme.tileToExtent( 0, 0, 0 ); extent = extent.intersect( &fullExtent ); JobData jd; jd.jobId = ++mLastJobId; jd.extent = extent; jd.timer.start(); // make a clone of the data provider so it is safe to use in worker thread jd.future = QtConcurrent::run( _readDtmData, mClonedProvider, extent, mResolution ); QFutureWatcher<QByteArray> *fw = new QFutureWatcher<QByteArray>; fw->setFuture( jd.future ); connect( fw, &QFutureWatcher<QByteArray>::finished, this, &QgsDemHeightMapGenerator::onFutureFinished ); mJobs.insert( fw, jd ); return jd.jobId; }
void PatternManager::thresholdImages() { qDebug() << "img thresholding"; if (!m_mtWatchers.isEmpty()) { qDebug("Error: the watchers queue is not empty!"); return; } //Fix me this synchronous logic and not threadsafe... mt_grayDecoder decoder2; std::vector<cv::Mat*> orgStdVec = m_originalPatterns.toStdVector(); min = *decoder2.findExtremeMinPixels(&orgStdVec); max = *decoder2.findExtremeMaxPixels(&orgStdVec); diff = *decoder2.findExtremeMinMaxDiffPixels(min, max); QVectorIterator<cv::Mat*> it(m_originalPatterns); while ( it.hasNext() ) { cv::Mat* origPtr = it.next(); QFutureWatcher<cv::Mat*>* mtWatcher = new QFutureWatcher<cv::Mat*>(); //QObject::connect(mtWatcher, SIGNAL(finished)), this, SLOT(fileLoaded(cv::Mat*)) QObject::connect(mtWatcher, SIGNAL(finished()), this, SLOT(thresholdImageFinished())); mt_grayDecoder decoder; QFuture<cv::Mat*> thresholder = QtConcurrent::run(decoder, &mt_grayDecoder::thresholdImage, origPtr, min, diff); mtWatcher->setFuture(thresholder); //m_mtWatchers.enqueue(mtWatcher); qDebug() << "img thresholding"; } }
bool PatternManager::loadFiles(QStringList fileNames) { if (!m_mtWatchers.isEmpty()) { qDebug("Error: the watchers queue is not empty!"); return false; } //clear current contents clearOriginalPatterns(); //save the size of the list of filenames patternSetSize = fileNames.size(); emit patternSetSizeSet(fileNames.size()); //iterate the filenames QStringListIterator it(fileNames); while ( it.hasNext() ) { QString fileName = it.next(); QFutureWatcher<cv::Mat*>* mtWatcher = new QFutureWatcher<cv::Mat*>(); //this doesn't work because of the while loop at the end QObject::connect(mtWatcher, SIGNAL(finished()), this, SLOT(fileLoadFinished())); //class method only works with internal member methods (not static so you need an instance) //see thresholdImage //mt_grayDecoder decoder;// = new mt_grayDecoder(); //QFuture<cv::Mat*> fileLoader = QtConcurrent::run(decoder, &mt_grayDecoder::loadFile, fileName.toStdString()); //static method only works with static methods in the class(simple) QFuture<cv::Mat*> fileLoader = QtConcurrent::run(mt_grayDecoder::loadFile, fileName.toStdString()); mtWatcher->setFuture(fileLoader); //m_mtWatchers.enqueue(mtWatcher); qDebug() << "file "<< fileName << " loading"; } return true; }
void EditTagDialog::SetSongsFinished() { QFutureWatcher<QList<Data> >* watcher = dynamic_cast<QFutureWatcher<QList<Data> >*>(sender()); if (!watcher) return; watcher->deleteLater(); if (!SetLoading(QString())) return; data_ = watcher->result(); if (data_.count() == 0) { // If there were no valid songs, disable everything ui_->song_list->setEnabled(false); ui_->tab_widget->setEnabled(false); // Show a summary with empty information UpdateSummaryTab(Song()); ui_->tab_widget->setCurrentWidget(ui_->summary_tab); SetSongListVisibility(false); return; } // Add the filenames to the list for (const Data& data : data_) { ui_->song_list->addItem(data.current_.basefilename()); } // Select all ui_->song_list->setCurrentRow(0); ui_->song_list->selectAll(); // Hide the list if there's only one song in it SetSongListVisibility(data_.count() != 1); }
void BaseFileFind::runSearch(Find::SearchResult *search) { FileFindParameters parameters = search->userData().value<FileFindParameters>(); CountingLabel *label = new CountingLabel; connect(search, SIGNAL(countChanged(int)), label, SLOT(updateCount(int))); Find::SearchResultWindow::instance()->popup(true); QFutureWatcher<FileSearchResultList> *watcher = new QFutureWatcher<FileSearchResultList>(); m_watchers.insert(watcher, search); watcher->setPendingResultsLimit(1); connect(watcher, SIGNAL(resultReadyAt(int)), this, SLOT(displayResult(int))); connect(watcher, SIGNAL(finished()), this, SLOT(searchFinished())); if (parameters.flags & Find::FindRegularExpression) { watcher->setFuture(Utils::findInFilesRegExp(parameters.text, files(parameters.nameFilters, parameters.additionalParameters), textDocumentFlagsForFindFlags(parameters.flags), ITextEditor::openedTextEditorsContents())); } else { watcher->setFuture(Utils::findInFiles(parameters.text, files(parameters.nameFilters, parameters.additionalParameters), textDocumentFlagsForFindFlags(parameters.flags), ITextEditor::openedTextEditorsContents())); } Core::FutureProgress *progress = Core::ICore::progressManager()->addTask(watcher->future(), tr("Search"), QLatin1String(Constants::TASK_SEARCH)); progress->setWidget(label); connect(progress, SIGNAL(clicked()), search, SLOT(popup())); }
void JamendoService::DownloadDirectoryFinished() { QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender()); Q_ASSERT(reply); app_->task_manager()->SetTaskFinished(load_database_task_id_); load_database_task_id_ = 0; // TODO: Not leak reply. QtIOCompressor* gzip = new QtIOCompressor(reply); gzip->setStreamFormat(QtIOCompressor::GzipFormat); if (!gzip->open(QIODevice::ReadOnly)) { qLog(Warning) << "Jamendo library not in gzip format"; delete gzip; return; } load_database_task_id_ = app_->task_manager()->StartTask(tr("Parsing Jamendo catalogue")); QFuture<void> future = QtConcurrent::run(this, &JamendoService::ParseDirectory, gzip); QFutureWatcher<void>* watcher = new QFutureWatcher<void>(); watcher->setFuture(future); connect(watcher, SIGNAL(finished()), SLOT(ParseDirectoryFinished())); }
void SpellCheckerCore::futureFinished() { /* Get the watcher from the sender() of the signal that invoked this slot. * reinterpret_cast is used since qobject_cast is not valid of template * classes since the template class does not have the Q_OBJECT macro. */ QFutureWatcher<WordList>* watcher = reinterpret_cast<QFutureWatcher<WordList>*>( sender() ); if( watcher == nullptr ) { return; } if( d->shuttingDown == true ) { /* Application shutting down, should not try something */ return; } if( watcher->isCanceled() == true ) { /* Application is shutting down */ return; } /* Get the list of words with spelling mistakes from the future. */ WordList checkedWords = watcher->result(); QMutexLocker locker( &d->futureMutex ); /* Recheck again after getting the lock. */ if( d->shuttingDown == true ) { return; } /* Get the file name associated with this future and the misspelled * words. */ FutureWatcherMapIter iter = d->futureWatchers.find( watcher ); if( iter == d->futureWatchers.end() ) { return; } QString fileName = iter.value(); /* Remove the watcher from the list of running watchers and the file that * kept track of the file getting spell checked. */ d->futureWatchers.erase( iter ); d->filesInProcess.removeAll( fileName ); /* Check if the file was scheduled for a re-check. As discussed previously, * if a spell check was requested for a file that had a future already in * progress, it was scheduled for a re-check as soon as the in progress one * completes. If it was scheduled, restart it using the normal slot. */ QHash<QString, WordList>::iterator waitingIter = d->filesWaitingForProcess.find( fileName ); if( waitingIter != d->filesWaitingForProcess.end() ) { WordList wordsToSpellCheck = waitingIter.value(); /* remove the file and words from the scheduled list. */ d->filesWaitingForProcess.erase( waitingIter ); locker.unlock(); /* Invoke the method to make sure that it gets called from the main thread. * This will most probably be already in the main thread, but to make sure * it is done like this. */ this->metaObject()->invokeMethod( this , "spellcheckWordsFromParser" , Qt::QueuedConnection , Q_ARG( QString, fileName ) , Q_ARG( SpellChecker::WordList, wordsToSpellCheck ) ); } locker.unlock(); watcher->deleteLater(); /* Add the list of misspelled words to the mistakes model */ addMisspelledWords( fileName, checkedWords ); }
void downloadFile() { QTemporaryFile file; file.setAutoRemove(false); if (file.open()) { const QString filename = file.fileName(); QInstaller::blockingWrite(&file, QByteArray(scLargeSize, '1')); file.close(); DownloadFileTask fileTask(QLatin1String("file:///") + filename); QFutureWatcher<FileTaskResult> watcher; QSignalSpy started(&watcher, SIGNAL(started())); QSignalSpy finished(&watcher, SIGNAL(finished())); QSignalSpy progress(&watcher, SIGNAL(progressValueChanged(int))); watcher.setFuture(QtConcurrent::run(&DownloadFileTask::doTask, &fileTask)); watcher.waitForFinished(); QTest::qWait(10); // Spin the event loop to deliver queued signals. QCOMPARE(started.count(), 1); QCOMPARE(finished.count(), 1); FileTaskResult result = watcher.result(); QCOMPARE(watcher.future().resultCount(), 1); QVERIFY(QFile(result.target()).exists()); QCOMPARE(file.size(), QFile(result.target()).size()); QCOMPARE(result.checkSum().toHex(), QByteArray("85304f87b8d90554a63c6f6d1e9cc974fbef8d32")); } }
int64_t DownloadSizeFinder::downloadOrQueue(const QString &url, QString *err) { int64_t r = -2; *err = ""; this->mutex.lock(); if (this->files.contains(url)) { QString v = this->files.value(url); if (v.startsWith('*')) *err = v.mid(1); else r = v.toLongLong(); this->mutex.unlock(); } else { this->mutex.unlock(); QFuture<DownloadFile> future = run(&threadPool, this, &DownloadSizeFinder::downloadRunnable, url); QFutureWatcher<DownloadFile>* w = new QFutureWatcher<DownloadFile>(this); connect(w, SIGNAL(finished()), this, SLOT(watcherFinished())); w->setFuture(future); } return r; }
void TFutureProgressPrivate::_q_SetStarted() { Progress->Reset(); Progress->SetError(false); Progress->SetRange(Watcher.progressMinimum(), Watcher.progressMaximum()); Progress->SetValue(Watcher.progressValue()); }
void KWin::Script::slotScriptLoadedFromFile() { QFutureWatcher<QByteArray> *watcher = dynamic_cast< QFutureWatcher< QByteArray>* >(sender()); if (!watcher) { // not invoked from a QFutureWatcher return; } if (watcher->result().isNull()) { // do not load empty script deleteLater(); watcher->deleteLater(); return; } QScriptValue optionsValue = m_engine->newQObject(options, QScriptEngine::QtOwnership, QScriptEngine::ExcludeSuperClassContents | QScriptEngine::ExcludeDeleteLater); m_engine->globalObject().setProperty(QStringLiteral("options"), optionsValue, QScriptValue::Undeletable); m_engine->globalObject().setProperty(QStringLiteral("QTimer"), constructTimerClass(m_engine)); QObject::connect(m_engine, SIGNAL(signalHandlerException(QScriptValue)), this, SLOT(sigException(QScriptValue))); KWin::MetaScripting::supplyConfig(m_engine); installScriptFunctions(m_engine); QScriptValue ret = m_engine->evaluate(QString::fromUtf8(watcher->result())); if (ret.isError()) { sigException(ret); deleteLater(); } watcher->deleteLater(); setRunning(true); m_starting = false; }
sqlqueryresultlist searchhandler::perform_grep(QString searchtxt, sqlqueryresultlist searchlist, bool exactmatch) { QVector<QString> strvec; sqlqueryresultlist resultlist; QFutureWatcher<sqlqueryresultlist> futureWatcher; QProgressDialog dialog; unsigned int n = searchlist.resultlist.size(); if (n == 0) return resultlist; strvec.resize(n); for (unsigned int i=0; i < n; i++) { strvec.replace(i, str2qt(searchlist.resultlist[i].filepath)); } dialog.setAutoReset(false); dialog.setLabelText(QString("Grep ").append(QString(tr("in progress"))).append(QString(" ..."))); dialog.setCancelButtonText(tr("Cancel")); QObject::connect(&futureWatcher, SIGNAL(finished()), &dialog, SLOT(reset())); QObject::connect(&dialog, SIGNAL(canceled()), &futureWatcher, SLOT(cancel())); QObject::connect(&futureWatcher, SIGNAL(progressRangeChanged(int,int)), &dialog, SLOT(setRange(int,int))); QObject::connect(&futureWatcher, SIGNAL(progressValueChanged(int)), &dialog, SLOT(setValue(int))); m_grepExactMatch = exactmatch; (*m_grepRegExp) = QRegExp(searchtxt.toAscii().data(), Qt::CaseInsensitive); m_grepRegExp->setPatternSyntax(QRegExp::RegExp2); futureWatcher.setFuture(QtConcurrent::mappedReduced(strvec, doGrep, collateGrep, QtConcurrent::SequentialReduce)); dialog.exec(); futureWatcher.waitForFinished(); if (futureWatcher.isCanceled() == false) resultlist = futureWatcher.result(); return resultlist; }
void ProgressManagerPrivate::updateSummaryProgressBar() { m_summaryProgressBar->setError(hasError()); updateVisibility(); if (m_runningTasks.isEmpty()) { m_summaryProgressBar->setFinished(true); if (m_taskList.isEmpty() || isLastFading()) fadeAwaySummaryProgress(); return; } stopFadeOfSummaryProgress(); m_summaryProgressBar->setFinished(false); QMapIterator<QFutureWatcher<void> *, Id> it(m_runningTasks); static const int TASK_RANGE = 100; int value = 0; while (it.hasNext()) { it.next(); QFutureWatcher<void> *watcher = it.key(); int min = watcher->progressMinimum(); int range = watcher->progressMaximum() - min; if (range > 0) value += TASK_RANGE * (watcher->progressValue() - min) / range; } m_summaryProgressBar->setRange(0, TASK_RANGE * m_runningTasks.size()); m_summaryProgressBar->setValue(value); }
QFuture<void> QgsGeometryChecker::execute( int *totalSteps ) { if ( totalSteps ) { *totalSteps = 0; for ( QgsGeometryCheck *check : qgis::as_const( mChecks ) ) { for ( auto it = mContext->featurePools.constBegin(); it != mContext->featurePools.constEnd(); ++it ) { if ( check->getCheckType() <= QgsGeometryCheck::FeatureCheck ) { *totalSteps += check->getCompatibility( it.value()->getLayer()->geometryType() ) ? it.value()->getFeatureIds().size() : 0; } else { *totalSteps += 1; } } } } QFuture<void> future = QtConcurrent::map( mChecks, RunCheckWrapper( this ) ); QFutureWatcher<void> *watcher = new QFutureWatcher<void>(); watcher->setFuture( future ); QTimer *timer = new QTimer(); connect( timer, &QTimer::timeout, this, &QgsGeometryChecker::emitProgressValue ); connect( watcher, &QFutureWatcherBase::finished, timer, &QObject::deleteLater ); connect( watcher, &QFutureWatcherBase::finished, watcher, &QObject::deleteLater ); timer->start( 500 ); return future; }
QVariant ThumbnailModel::data(const QModelIndex &index, int role) const { if (role == Qt::DecorationRole && index.isValid()) { QString id = itemId(index).toString(); QFutureWatcher<QImage> *future = cache.object(id); if (!future) { future = new QFutureWatcher<QImage>; QString path = imagePath(index); if (!path.isEmpty()) { future->setFuture(QtConcurrent::run(ThumbnailModel::load, path)); connect(future, SIGNAL(finished()), this, SLOT(thumbnailLoaded())); } cache.insert(id, future); } return !future->isCanceled() ? future->result() : QVariant(); } else { return QGalleryQueryModel::data(index, role); } }
void BaseFileFind::runSearch(SearchResult *search) { FileFindParameters parameters = search->userData().value<FileFindParameters>(); CountingLabel *label = new CountingLabel; connect(search, &SearchResult::countChanged, label, &CountingLabel::updateCount); CountingLabel *statusLabel = new CountingLabel; connect(search, &SearchResult::countChanged, statusLabel, &CountingLabel::updateCount); SearchResultWindow::instance()->popup(IOutputPane::Flags(IOutputPane::ModeSwitch|IOutputPane::WithFocus)); QFutureWatcher<FileSearchResultList> *watcher = new QFutureWatcher<FileSearchResultList>(); d->m_watchers.insert(watcher, search); watcher->setPendingResultsLimit(1); connect(watcher, &QFutureWatcherBase::resultReadyAt, this, &BaseFileFind::displayResult); connect(watcher, &QFutureWatcherBase::finished, this, &BaseFileFind::searchFinished); if (parameters.flags & FindRegularExpression) { watcher->setFuture(Utils::findInFilesRegExp(parameters.text, files(parameters.nameFilters, parameters.additionalParameters), textDocumentFlagsForFindFlags(parameters.flags), TextDocument::openedTextDocumentContents())); } else { watcher->setFuture(Utils::findInFiles(parameters.text, files(parameters.nameFilters, parameters.additionalParameters), textDocumentFlagsForFindFlags(parameters.flags), TextDocument::openedTextDocumentContents())); } FutureProgress *progress = ProgressManager::addTask(watcher->future(), tr("Searching"), Constants::TASK_SEARCH); progress->setWidget(label); progress->setStatusBarWidget(statusLabel); connect(progress, &FutureProgress::clicked, search, &SearchResult::popup); }
QPixmap CoverArtCache::requestCover(const CoverInfo& requestInfo, const QObject* pRequestor, int requestReference, const int desiredWidth, const bool onlyCached, const bool signalWhenDone) { if (sDebug) { qDebug() << "CoverArtCache::requestCover" << requestInfo << pRequestor << requestReference << desiredWidth << onlyCached << signalWhenDone; } if (requestInfo.type == CoverInfo::NONE) { if (signalWhenDone) { emit(coverFound(pRequestor, requestReference, requestInfo, QPixmap(), true)); } return QPixmap(); } // keep a list of trackIds for which a future is currently running // to avoid loading the same picture again while we are loading it QPair<const QObject*, int> requestId = qMakePair(pRequestor, requestReference); if (m_runningRequests.contains(requestId)) { return QPixmap(); } // If this request comes from CoverDelegate (table view), it'll want to get // a cropped cover which is ready to be drawn in the table view (cover art // column). It's very important to keep the cropped covers in cache because // it avoids having to rescale+crop it ALWAYS (which brings a lot of // performance issues). QString cacheKey = CoverArtUtils::pixmapCacheKey(requestInfo.hash, desiredWidth); QPixmap pixmap; if (QPixmapCache::find(cacheKey, &pixmap)) { if (signalWhenDone) { emit(coverFound(pRequestor, requestReference, requestInfo, pixmap, true)); } return pixmap; } if (onlyCached) { if (sDebug) { qDebug() << "CoverArtCache::requestCover cache miss"; } return QPixmap(); } m_runningRequests.insert(requestId); QFutureWatcher<FutureResult>* watcher = new QFutureWatcher<FutureResult>(this); QFuture<FutureResult> future = QtConcurrent::run( this, &CoverArtCache::loadCover, requestInfo, pRequestor, requestReference, desiredWidth, signalWhenDone); connect(watcher, SIGNAL(finished()), this, SLOT(coverLoaded())); watcher->setFuture(future); return QPixmap(); }
int ServerListener::run() { QFuture<int> future = QtConcurrent::run(this, &ServerListener::concurrentServerListener); QFutureWatcher<int> watcher; watcher.setFuture(future); return 0; }
void tst_QFutureWatcher::resultAt() { QFutureWatcher<int> futureWatcher; futureWatcher.setFuture((new IntTask())->start()); futureWatcher.waitForFinished(); QCOMPARE(futureWatcher.result(), 10); QCOMPARE(futureWatcher.resultAt(0), 10); }