Concurrent map equivalent
-
I just realized something... if though it's working, if I close the window it will continue running...
What can I do?
-
@Defohin
Hi , i think you can cancel via
http://doc.qt.io/qt-5/qfuture.html#cancel
http://doc.qt.io/qt-5/qfuturewatcher.html#cancelI think you need to use QFutureWatcher if u dont use waitForFinished.
All credits to @kshegunov :) -
@Defohin
Oh. not all can be canceled. :(
Well if u need to be able to stop at random then
threads might be the best solution. -
I don't want the pause, continue or the stop function, I just want to run a list of string over a method and pass additional arguments to it in parallel.
UsingQtConcurrent::map
won't work cause I can't pass additional arguments.
UsingQtConcurrent::run
won't work cause I'll need to callwaitForFinished
and it will block the GUI thread... (QFutureWatcher::cancel
orQFuture::cancel
won't work either cause it's not possible to cancel aQFuture
returned byQtConcurrent::run
)...What can I do? I'm out of ideas.
-
like this:
QStringList names = { "john", "jane" }; // global or member variable void YourClass::startJobs() { QString extra = "doe"; auto example = [extra] (QString &name) { qDebug() << name << extra; }; QFuture<void> future = QtConcurrent::map(names, example); }
-
Hi
If cancel is a MUST have, then QThreads seems the only option :( -
@Devopia53 It's still crashing for me.
@mrjj I don't want to usecancel
, as i said, I just want to run in parallel the method for each item of a string list and pass a few additional arguments. No need to cancel. -
@Defohin said in Concurrent map equivalent:
No need to cancel.
By cancel i mean to terminate before its finished. Like closing program.
In that regards you need "cancel" :) -
@mrjj Yes, if the application is closed I want to finish the threads as well. I thought it was a default behavior.
Can you give me an example of what I can do? I'm trying to use
QRunnable
, but I have no idea if it's going to work. -
@Defohin said in Concurrent map equivalent:
Using QtConcurrent::map won't work cause I can't pass additional arguments.
Just use a function object
struct MapHelper{ MapHelper(){} QString m_additionalArgument1; QString m_additionalArgument2; typedef QString result_type; QString operator()(const QString &val) { return m_additionalArgument1+val+additionalArgument2; } } MapHelper helper; // TODO: make sure to manage its lifecycle helper.m_additionalArgument1 = "Prefix "; helper.m_additionalArgument2 = " Suffix"; QtConcurrent::map(list_of_names,helper);
-
@VRonin How to get the return from each one now?
struct NameHelper { NameHelper(const QString &extra) : _extra(extra) { } typedef QString result_type; QString operator()(const QString &name) { return QString("Hello %1 %2").arg(name).arg(_extra); } QString _extra; }; QStringList names = { "john", "jane" }; QString extra = "doe"; QFuture<QString> example = QtConcurrent::mapped(names, NameHelper(extra));
example.result()
is returning only"Hello john doe"
. -
You can achieve the same with C++11 std::bind:
QString concatenate(const QString& prefix,const QString& val,const QString& suffix){return prefix+val+suffix;} QtConcurrent::mapped(list_of_names,std::bind(concatenate,"Prefix ",std::placeholders::_1," Suffix"));
How to get the return from each one now?
[...]
example.result() is returning only "Hello john doe".use
results()
instead ofresult()
-
It's working nicely, but one last question; Is it GUI blocking? I tried to use a for loop inside of the function and it's now showing anything until it's finished.
-
@Defohin said in Concurrent map equivalent:
Is it GUI blocking?
no, unless you force it to be
I tried to use a for loop inside of the function
could you post the code?
-
struct NameHelper { NameHelper(const QString &extra) : _extra(extra) { } typedef QString result_type; QString operator()(const QString &name) { for(int i = 0; i < 999999; ++i) { qDebug() << "block"; } return QString("Hello %1 %2").arg(name).arg(_extra); } QString _extra; }; QStringList names = { "john", "jane" }; QString extra = "doe"; QFuture<QString> example = QtConcurrent::mapped(names, NameHelper(extra));
-
operator()
will be executed in another thread, it will not block the GUI thread, it will not return until completed (of course) -
@Defohin said in Concurrent map equivalent:
But why is it not appearing the window If it's running in another thread?
WOW! we are taking this on a whole new level here! you need a QFutureWatcher on the QFuture and a slot connected to the
resultReadyAt
signal to display the results in the GUI
18/35