[Qt-interest] connection between qthreads blocks my gui

franki franki at franki.eu.org
Wed Dec 15 14:22:10 CET 2010


Wednesday 15 of December 2010 10:07:21 Sean Harmer napisał(a):
> Hi,
>
> On Tuesday 14 December 2010 18:25:03 franki wrote:
> > I have some gui class (mainClass), inside that class I created two
> > classes which subclass QThread, one of which is sending/receiving data
> > from rs232, lets say rs232Thread, second one is sending signal to start
> > reading from rs232,lets say cronThread. Connection is defined inside
> > mainClass like this:
> > connect(cronThread,SIGNAL(startChecking()),rs232Thread,SLOT(readWrite()),
> >Q t::QueuedConnection)
> >
> > Problem is, that this readWrite function blocks my entire gui when
> > running, and as I read somewhere in case of QueuedConnection, the SLOT is
> > executed inside receiver's thread, so why is this blocking my gui?
> >
> > The only way I can do it without blocking gui is to place function
> > readWrite inside run() of this rs232Thread and connect signal from
> > cronThread to some function (defined in rs232Thread) which starts run().
> >
> > What am I doing wrong? Is this a problem that connection between this two
> > threads is defined inside mainClass (which is gui thread) ? Or there is
> > something else?
>
> This should really be on an FAQ somewhere. The section of the docs you need
> to read and understand is this:
>
> http://doc.qt.nokia.com/latest/threads-qobject.html
>
> As K Frank and others mentioned you need to be careful if you want to put
> slots directly onto your QThread class. To avoid confusion it is often
> clearer to use a worker QObject that lives within and has affinitiy with
> your QThread object.
>
> Please see the attached example to see how this pattern generally works. We
> do exactly this kind of thing over rs232 comms too and it works a treat.

Well this example seems to be far more advanced than what I was doing so far.
Correct me please if I'm wrong.
You create DataProcessor object which has affinity to main thread, but in 
constructor you create another thread from PollingThread, and you store it in 
private variable 
PollingThread* m_workerThread
This m_workerThread creates DevicePoller which is simply object living inside 
new thread and doing all rs232 communication (invoked by QTimer). (in my case 
it would be rs232Manager that talks to devices on this separate thread, and 
then sends the results to my guiClass - an equivalent of DataProcessor) 
Now, talking to device through rs232 must be serialized, which means one 
operation at the time, so DevicePoller living in QThread queries devices and 
sends results to DataProcessor one by one.

To sum up, in the end we have two threads, one is main thread where 
DataProcessor object lives, the second one is thread subclassed from QThread, 
which has an object DevicePoller which queries devices and sends results to 
main thread.
If it's correct (and I'm not sure I got the hang of it) it seems there is 
small mistake inside DataProcessor::DataProcessor constructor when you 
connect SIGNAL, the sender object should be m_workerThread->m_poller instead 
of m_workerThread->poller()

It is a fine example to query devices, althought in my case it should also 
contain some signal-slot connection in opposite direction. Because when user 
twists a QDial (wich has tracking on) this object needs to send lets say 50 
requests to device to change lets say voltage smoothly from the value QDial 
was set at the beginning to the new position. In that case worker thread will 
have to queue these operation and perform it one by one.

many thanks
Marek

>
> ATB,
>
> Sean





More information about the Qt-interest-old mailing list