event & signals & threads

The Event System
http://doc.qt.io/qt-4.8/eventsandfilters.html

Each thread can have its own event loop. The initial thread starts its event loops using QCoreApplication::exec(); 
other threads can start an event loop using QThread::exec().

 

Qt signals (QueuedConnection and DirectConnection) -- answer from Jacob Robbins
http://stackoverflow.com/questions/15051553/qt-signals-queuedconnection-and-directconnection

You won't see much of a difference unless you're working with objects having different thread affinities.
Let's say you have QObjects A and B and they're both attached to different threads. A has a signal called somethingChanged() and B has a slot called handleChange(). If you use a direct connection:
  connect( A, SIGNAL(somethingChanged()), B, SLOT(handleChange()), Qt::DirectConnection );
the method handleChange() will actually run in the A's thread. Basically, it's as if emitting the signal calls the slot method "directly".
If B::handleChange() isn't thread-safe, this can cause some (difficult to locate) bugs. At the very least, you're missing out on the benefits of the extra thread.

If you change the connection method to Qt::QueuedConnection (or, in this case, let Qt decide which method to use), Assuming B's thread is running an event loop, emitting the signal will post an event to B's event loop. 
The event loop queues the event, and eventually invokes the slot method whenever control returns to it (it being the event loop).
This makes it pretty easy to deal with communication between/among threads in Qt (again, assuming your threads are running their own local event loops).
You don't have to worry about locks, etc. because the event loop serializes the slot invocations.

Note: If you don't know how to change a QObject's thread affinity, look into QObject::moveToThread.

It does make a difference if you specify a queued connection - even for two objects on the same thread.
The event is still posted to the thread's event loop. So, the method call is still asynchronous, meaning it can be delayed in unpredictable ways
(depending on any other events the loop may need to process).
However, if you don't specify a connection method, the direct method is automatically used for connections between objects on the same thread (at least it is in Qt 4.8).

Threads and QObjects
http://doc.qt.io/qt-4.8/threads-qobject.html

Signals & Slots
http://doc.qt.io/qt-4.8/signalsandslots.html

(DirectConnection)Execution of the code following the emit statement will occur once all slots have returned.
The situation is slightly different when using queued connections; in such a case, the code following the emit
keyword will continue immediately, and the slots will be executed later.

 example:

// file :signal.h
#include <QObject>
class Counter: public QObject
{
    Q_OBJECT
    public:
        Counter(){m_value=0;}
        int value() const{return m_value;}
    public slots:
        void setValue(int value);
    signals:
        void valueChanged(int value);
    private:
        int m_value;
};
// file : signal.cpp
#include "signal.h"
#include <iostream>
void Counter::setValue(int value)
{   
    if(value!=m_value)
    {
        m_value = value;
        emit valueChanged(value);
    }
}   

int main(int argc, char **argv)
{
    Counter a,b;
    QObject::connect(&a, SIGNAL(valueChanged(int)),&b,SIGNAL(valueChanged(int)));
    QObject::connect(&b, SIGNAL(valueChanged(int)),&b,SLOT(setValue(int)));
    a.setValue(33);
    std::cout << "value of a :" << a.value() << std::endl;
    std::cout << "value of b :" << b.value() << std::endl;
    std::cin.get();
}
~ 

to compile them: qmake -project; qmake; make

note: the declaration of class Counter should put in header file, for MOC will only anlyse header files and create corresponding moc file

posted @ 2017-04-05 11:26  HEIS老妖  阅读(176)  评论(0编辑  收藏  举报