[Qt-interest] Threading and objects...

BRM bm_witness at yahoo.com
Fri Nov 12 16:45:39 CET 2010


----- Original Message ----

> From: Sean Harmer <sean.harmer at maps-technology.com>
> On Friday 12 November 2010 13:46:22 K. Frank wrote:
> > Hello  Sean and Everyone -
> > <sean.harmer at maps-technology.com>  wrote:
> > > On Thursday 11 November 2010 16:54:36 BRM wrote:
> >  >> I have been doing quite a bit of multithreading with Qt for a while;  
and
> > >> recently read (on the Qt blogs, a couple months back[1])  about the
> > >> "right way" to use QThread;
> >  > <snip>
> > > 
> > >> In my new approach, I'm trying  to keep the same basic architecture, at
> > >> least for now while I  get to figure out the new approach -
> > >  <snip>
> > > 
> > > The approach that I normally take to  this is to have a trivial subclass
> > > of QThread that contains as  members pointers to the one or more objects
> > > that actually do the  work in the context of the thread.
> > > 
> > > There is no need  to have forwarding signals from the thread class itself.
> > > Just  expose the pointers to the worker objects, then you can simply use
> > >  them to make connections between the worker objects and whatever else
> >  > you have.
> > > 
> > > I normally create the worker objects  inside the run() function of my
> > > QThread subclass. The only thing to  be careful of is to make sure that
> > > your object is created before  you try to use it in a connect() call. To
> > > help with this I usually  use a simple waitForStart() function (see
> > > attached example). The  alternative is to use moveToThread() but I find
> > > this less  maintainable.
> > 
> > On the  other hand, why not...?
> > 
> > First, what your doing seems to make good sense, and is nice  and
> > organized -- my question is about mulling over alternatives, and  is
> > not to suggest that your choice isn't as good or better.
> > 
> > So, why not subclass QThread to give it the functionality of its  primary
> > worker object, and moveToThread it to itself when it's  instantiated,
> > presumably in its constructor, or something?
<snip> 
> I guess it's just how I visualise the concepts  encapsulated by QThread. I tend 
>
> to think of QThread as a class to manage a  thread rather than as a way of 
> doing work within that thread.
> 
> The  main advantage to me is that it keeps the conceptual model clearer in my 
> (little) brain ;-). 
> 
> It also allows me to reuse the worker objects in  the main thread or in some 
> other worker thread that also uses additional  objects without being tied into 

> a specific QThread subclass and then havong  to refactor things later. 

While I didn't provide it in my examples, the QThread signals are identical 
mirrors of what comes in and out of the internal object it is managing - e.g the 
QMyThreadInstance.
So, you can easily pull the instance object out of the thread and use it 
elsewhere - I also put it in its own header and implementation files. Point is, 
whether you are
sub-classing QThread or not, the work can be the same. The only difference is 
whether you specify to use slots to the object versus signals.

My goal with the new method was to try to eliminate some of the maintenance work 
- get to where I can just create the worker object and hand it off to a plain 
QThread instance via moveToThread(); perhaps even going to the point of having 
something similar to QThreadPool that can spawn off QThreads and assign a 
QObject to them, as opposed to being oriented towards distributed computing with 
QRunnable. My overall goal is for creating a Qt-based platform for which I can 
build software easily, reliably, and quickly.

However, getting back to my original issue - I was running into a problem where 
I am getting an error with this method:

QObject::setParent: Cannot set parent, new parent is in a different thread
 
I finally did locate the issue - in the following lines:

// this use to be done by the allocating class
existing_connection.setParent(NULL); // ensure no parent is set!
existing_connection.moveToThread(actualThread); // move it to the new thread
threadRunner = new QMyThreadInstance(existing_connection,NULL);

What I didn't show is that the QMyThreadInstance() does parent the 
existing_connection object. However, the above moved it to the new thread first, 
thus the error message.
Removing those two lines solves the issue. They are actually not needed since 
moveToThread() also moves all child objects to the new thread as well.

TIA,

Ben

[1]http://lists.trolltech.com/pipermail/qt-interest/2010-November/029058.html




More information about the Qt-interest-old mailing list