[Interest] Heavily Commented Example: Simple Single Frontend with Two Backends

Bo Thorsen bo at fioniasoftware.dk
Wed Oct 24 09:12:52 CEST 2012

Den 23-10-2012 22:28, d3fault skrev:
> On 10/22/12, Bo Thorsen <bo at fioniasoftware.dk> wrote:
>> Now I'm getting annoyed. You're the one spreading misinformation here. I
>> mentioned the pure computation as one of the cases where I prefer
>> subclassing. But that of course doesn't mean you can't do it in other ways.
> You're right, I was mainly focusing on your pure computation argument
> in my response. Thought you were arguing that moveToThread couldn't do
> it. ("emitting progress signals can take it off the list" -- what??
> meh don't bother responding, it's pointless)
> But anyways I've been following the [higher level] topics in this
> thread and now I'm thinking the example in the .zip needs a complete
> rewrite haha.
> Here, I'm about to contradict my earlier self:
> In order to have both the constructor and destructor run on the
> thread, would it be a good idea to do something like this?
> run()
> {
> 	UserObject obj; //ideally this would be a template passed in to some
> custom QThread implementation, but it's important to note that it is
> allocated on the stack
> 	emit readyForConnections(&obj); //Would be dangerous to call methods
> etc on this object. Should only connect to it's signals/slots
> 	exec();
> 	//destructor runs when exec() returns... ie when thread is
> ending/about-to-end. Since we're still in run(), the destructor runs
> on the thread :)
> }
> ...so you could set up an object on it's own thread (incl.
> constructor/destructor!) by doing:
> LoLCustomThreadImplWithATemplateToo<MyObjectType> threadForMyObject;
> connect(&threadForMyObject,
> SIGNAL(readyForConnections(MyObjectType*)), this,
> SLOT(handleObjectReadyForConnections(MyObjectType*)));
> threadForMyObject.start();
> void handleObjectReadyForConnections(MyObjectType *obj)
> {
> 	connect(btn, SIGNAL(clicked()), obj, SLOT(doSomethingPleaseAndThankYou()));
> 	connect(obj, SIGNAL(somethingHappenedDuuuude()), this,
> SLOT(handleSomeoneStoleMyCarDude()));
> 	//etc
> }
> New Qt class or what?

Hmm, not sure. It looks to me like the problem is again just moved 
somewhere else. The "Would be dangerous to call methods" comment shows 
this problem. Using a QThread is difficult to get right, so by trying to 
hide this fact, you could end up giving the impression that it isn't. I 
usually prefer exposing the problems to the developer, unless they can 
be removed by a helper class. In some cases you can do this, in the 
general QThread case you can't. Otherwise it would already have been done.

You mentioned that you considered rewriting the example to use one of 
the other ways. Thread pools or QtConcurrent are examples of helper 
classes that hide the complexity of QThread. It's not their purpose, 
though, but they are in this family of classes. But they have other 
reasons for existing because they add specific functionality.

Bo Thorsen.

Come by my DevDays talk in Berlin - "Designing for testability". Learn how to build and run your unit tests with the Qt application.

Fionia Software - Qt experts for hire.

More information about the Interest mailing list