View Full Version : Tangled in QThreads
spawn9997
13th October 2009, 19:49
I have an issue similar to this link http://www.qtcentre.org/forum/f-qt-programming-2/t-qthread-trying-to-limit-threads-23606.html/?highlight=QThread
I have tried to use the QtConcurrent::run function but it seems something is still wrong.
What I have is a long operation that calculates points that go on a map (QImage or QPixmap). I want the result to be a point list (QPolygonF) such that I can call QPainter::drawPoints(const QPolygonF & points). Now this works fine when I have 1 set of data. I want to split the job and get it done quicker by using say 2 (or more) calls to QtConcurrent::run on a part of the data.
The idea is to call them one after the other then wait for all of them to be done. For each one that finishes I can draw that polygon to the map; and, when done I have the full map.
What happens is I get one of them to finish but am baffled as to how to wait for all of the functions to return. I tried sub classing QThread but it seems when one instance of the thread is called the other returns immediately. Can I only call one instance of a sub class of QThread at a time?
Will provide code if needed.
JW
sw developer
caduel
13th October 2009, 20:15
QtConcurrent is supposed to be a higher level API that relieves you from having to work with QThread directly. How/why do you mix both?
Best show us some code, so we have a proper grounds for discussion.
spawn9997
13th October 2009, 21:01
Oh sorry, caduel, I have confused you. I first tried with QtConcurrent then I tried with QThread. Let me show you some code...
Here is the line that will call the function:
QtConcurrent::run(this,&MidpointSceneThread::getMidpoints,myStruct)
where myStruct is a bunch of data I need in the function.
defined as:
struct MidpointStruct {
QList<ShotGraphicsItem *> sgiList;
GeometryVersion *gvLocal;
int startIndex;
int size;
int decimateBy;
QImage image;
MidpointGraphicsLayer * mpgl;
};
ShotGraphicsItem and MidpointGraphicsLayer are types of QGraphicsItems,
declaration of function (it is a part of the class MidpointSceneThread):
QPolygonF MidpointSceneThread::getMidpoints(MidpointStruct &myStruct);
This function goes through the list of ShotGraphicsItems and does some calculations and returns a set of points (Midpoints) that I use to draw on a pixmap.
The issue is I want the list of ShotGraphicsItem to be broken up and I tried several things to get the future return items...
I tried making a loop and calling the run function 3 times...
More CODE:
for (int ndx = 0; ndx < numThreads; ++ndx){
QFuture<QPolygonF> midpoints[ndx] = QtConcurrent::run(this,&MidpointSceneThread::getMidpoints,myStruct[ndx]);
}
Is this even a proper way to split up the job? when I run this and call :
for (int ndx = 0; ndx < numThreads; ++ndx)
resultPoly[ndx] = midpoints[ndx].result();
I get the first one but the loop does not get the other 2 results and only part of the map is drawn.
I hope this makes it clearer what I'm asking.
JW
caduel
14th October 2009, 07:53
have you had a look at QtConcurrent::mapped()?
spawn9997
14th October 2009, 17:32
I have but I am in the middle of looking at it again. QtConcurrent::mapped() or QtConcurrent::blockingMapped() should work better than QtConcurrent::run. I see (not from documentation but from reading this forum) that the map style function must take 1 argument. Does that mean there is no way to use a class member function (method) with this? Is there a way around this?
jw
spawn9997
14th October 2009, 19:06
Thanks for the reference. After studying my code I found an error that caused only one of my threads to loop fully. After fixing this error now all threads complete. I also found out about
std::bind1st which allows me to use my member function with the concurrent Map function.
For all interested here is what I did:
function declaration:
QPolygonF MidpointSceneThread::partialDraw(MidpointStruct myStruct)
NOTE: You cannot use a reference type because of the bind function so I pass by value the struct 'myStruct'.
Then I call it like this:
QList<QPolygonF> polys = QtConcurrent::blockingMapped (structList,std::bind1st(std::mem_fun(&MidpointSceneThread::partialDraw),this));
when that returns I can use my List of polygons as I wish!!
Last question... is the use of std:bind1st not portable? I'm not familiar with some of the std:: functions.
JW
sw developer
caduel
14th October 2009, 19:24
have a look at Boost.Bind if you want to pass a (bound) member function;
there should be some threads here on how to use it, search for "boost::bind"
spawn9997
14th October 2009, 22:00
Thanks I'll do that.
Powered by vBulletin® Version 4.2.5 Copyright © 2024 vBulletin Solutions Inc. All rights reserved.