Re: [Interest] Emitting signal from QThread::run()

2016-02-29 Thread Bo Thorsen

Den 27-02-2016 kl. 07:15 skrev Syam:


Hello,

Inspired from the recent discussions on QThread, I have the following
question.
I have:

class MyThread : public QThread
{
Q_OBJECT
 //the constructor and other stuff

signals:
  void mySignal();

protected:
   virtual void run()
   {
  while(true)
  {
 //do something
 if(some_condition) emit mySignal();
  }
   }
};


void MainWindow::someFunction()
{
MyThread *thread = new MyThread;
connect(thread, SIGNAL(mySignal()), this, SLOT(myGuiSlot()),
Qt::QueuedConnection);
thread->start();
}


//

Will the above code work fine? In myGuiSlot() I am typically
manipulating some widgets - setting the text of a QLabel etc.


Don't ever do this. I don't subscribe to the idea that you should never 
subclass QThread yourself, but I think it's a very bad idea to subclass 
and use signals and slots.


The reason is the discussion that followed in this thread - it's so hard 
to understand precisely what happens with the connected signals and slots.


I usually tell people that QThread is a bridge between the creating and 
the created thread. It's not actually, but conceptually it helps them to 
realize that they should not assume they can understand the qobject 
thread affinity inside the object itself.


If you use signals and slots in a thread object, you do this:

QThread* thread = new QThread;
MyObject* object = new MyObject;
object->moveToThread(thread);
thread->start();

If you don't and only do calculation, or use a queue or something to 
handle the communication with hardware, etc, then you can subclass 
QThread and do stuff in run(). (This part is where I disagree with the 
"you're doing it wrong" crowd.) This is safe because without signals and 
slots in there you don't use the thread affinity and you don't have a 
local event loop.


Guys, this is only hard if you insist on doing something that 
experienced people say you should stay away from. The OP thought the 
MyObject should create it's own thread. No, that's wrong. Accept it and 
move on. Or create a wrapper object around it if you must encapsulate it.


Bo Thorsen,
Director, Viking Software.

--
Viking Software
Qt and C++ developers for hire
http://www.vikingsoft.eu
___
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest


Re: [Interest] Emitting signal from QThread::run()

2016-02-28 Thread Alejandro Exojo
El Sunday 28 February 2016, Sze Howe Koh escribió:
> > Will be queued without the explicit QueuedConnection? In other words,
> > what does AutoConnection do here? run() is executed in another thread,
> > but the QThread is in the same thread of MainWindow, right?
> 
> See http://doc.qt.io/qt-5/qt.html#ConnectionType-enum
> 
> "If the receiver lives in the thread that emits the signal,
> Qt::DirectConnection is used. Otherwise, Qt::QueuedConnection is used.
> The connection type is determined when the signal is emitted."
> 
> Qt checks to see which thread the signal is emitted from. Qt does not
> check which thread the signal sender lives in.

Thank you. I don't think that the documentation is totally clear in this 
regard. The quote you pasted has a link to the explanation of thread affinity 
which says:

"By default, a QObject lives in the thread in which it is created. An object's 
thread affinity can be queried using thread() and changed using 
moveToThread()."

In the context of the previous example, I wasn't entirely sure if this was a 
possibility:

1. The QThread-derived instance is created in the thread of MainWindow.
2. That instance is not moved to other thread, so it keeps the thread affinity 
of the MainWindow.
3. When a signal is emitted in run(), the thread affinity checked is somehow 
"stored" in the instance, and since moveToThread did not change it, it's still 
the same of MainWindow.

Now I have the confirmation that the 3rd point is wrong, which is good. :)

I think at some point (when learning about QThread, etc.) we've all checked it 
ourselves calling this->thread() and QThread::currentThread() to see what they 
returned. :)

-- 
Alex (a.k.a. suy) | GPG ID 0x0B8B0BC2
http://barnacity.net/ | http://disperso.net
___
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest


Re: [Interest] Emitting signal from QThread::run()

2016-02-27 Thread Sze Howe Koh
On 28 February 2016 at 00:26, Alejandro Exojo  wrote:
>
> El Saturday 27 February 2016, Thiago Macieira escribió:
> > On sábado, 27 de fevereiro de 2016 11:45:50 PST Syam wrote:
> > > void MainWindow::someFunction()
> > > {
> > >
> > >MyThread *thread = new MyThread;
> > >connect(thread, SIGNAL(mySignal()), this, SLOT(myGuiSlot()),
> > >
> > > Qt::QueuedConnection);
> > >
> > >thread->start();
> > >
> > > }
> > >
> > >
> > > //
> > >
> > > Will the above code work fine? In myGuiSlot() I am typically manipulating
> > > some widgets - setting the text of a QLabel etc.
> >
> > Yes. The signal will be queued anyway.
>
> Will be queued without the explicit QueuedConnection? In other words, what
> does AutoConnection do here? run() is executed in another thread, but the
> QThread is in the same thread of MainWindow, right?

See http://doc.qt.io/qt-5/qt.html#ConnectionType-enum

"If the receiver lives in the thread that emits the signal,
Qt::DirectConnection is used. Otherwise, Qt::QueuedConnection is used.
The connection type is determined when the signal is emitted."

Qt checks to see which thread the signal is emitted from. Qt does not
check which thread the signal sender lives in.


Regards,
Sze-Howe
___
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest


Re: [Interest] Emitting signal from QThread::run()

2016-02-27 Thread Thiago Macieira
On sábado, 27 de fevereiro de 2016 17:26:32 PST Alejandro Exojo wrote:
> El Saturday 27 February 2016, Thiago Macieira escribió:
> > On sábado, 27 de fevereiro de 2016 11:45:50 PST Syam wrote:
> > > void MainWindow::someFunction()
> > > {
> > > 
> > >MyThread *thread = new MyThread;
> > >connect(thread, SIGNAL(mySignal()), this, SLOT(myGuiSlot()),
> > > 
> > > Qt::QueuedConnection);
> > > 
> > >thread->start();
> > > 
> > > }
> > > 
> > > 
> > > //
> > > 
> > > Will the above code work fine? In myGuiSlot() I am typically
> > > manipulating
> > > some widgets - setting the text of a QLabel etc.
> > 
> > Yes. The signal will be queued anyway.
> 
> Will be queued without the explicit QueuedConnection? In other words, what
> does AutoConnection do here? run() is executed in another thread, but the
> QThread is in the same thread of MainWindow, right?

It would have been queued with AutoConnection, yes.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center

___
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest


Re: [Interest] Emitting signal from QThread::run()

2016-02-27 Thread Alejandro Exojo
El Saturday 27 February 2016, Thiago Macieira escribió:
> On sábado, 27 de fevereiro de 2016 11:45:50 PST Syam wrote:
> > void MainWindow::someFunction()
> > {
> > 
> >MyThread *thread = new MyThread;
> >connect(thread, SIGNAL(mySignal()), this, SLOT(myGuiSlot()),
> > 
> > Qt::QueuedConnection);
> > 
> >thread->start();
> > 
> > }
> > 
> > 
> > //
> > 
> > Will the above code work fine? In myGuiSlot() I am typically manipulating
> > some widgets - setting the text of a QLabel etc.
> 
> Yes. The signal will be queued anyway.

Will be queued without the explicit QueuedConnection? In other words, what 
does AutoConnection do here? run() is executed in another thread, but the 
QThread is in the same thread of MainWindow, right?

-- 
Alex (a.k.a. suy) | GPG ID 0x0B8B0BC2
http://barnacity.net/ | http://disperso.net
___
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest


Re: [Interest] Emitting signal from QThread::run()

2016-02-27 Thread Thiago Macieira
On sábado, 27 de fevereiro de 2016 11:45:50 PST Syam wrote:
> void MainWindow::someFunction()
> {
>MyThread *thread = new MyThread;
>connect(thread, SIGNAL(mySignal()), this, SLOT(myGuiSlot()),
> Qt::QueuedConnection);
>thread->start();
> }
> 
> 
> //
> 
> Will the above code work fine? In myGuiSlot() I am typically manipulating
> some widgets - setting the text of a QLabel etc.

Yes. The signal will be queued anyway.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center

___
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest