Qt的signal/slot机制原理


类型:C++ & Qt4,创建时间:Jan. 1, 2012, 11:49 a.m.

标题无“转载”即原创文章,版权所有。转载请注明来源:http://hgoldfish.com/blogs/article/41/。

signal/slot在底层会使用三种方式传递消息。参见QObject::connect()方法:

bool QObject::connect (const QObject * sender,
        const char *signal, const QObject *receiver,
        const char *method,
        Qt::ConnectionType type = Qt::AutoCompatConnection)

最后一个参数是就是传递消息的方式了,有四个取值:

  • Qt::DirectConnection

    When emitted, the signal is immediately delivered to the slot.

    假设当前有4个slot连接到QPushButton::clicked(bool),当按钮被按下时,QT就把这4个slot按连接的时间顺序调用一遍。显然这种方式不能跨线程(传递消息)。

  • Qt::QueuedConnection

    When emitted, the signal is queued until the event loop is able to deliver it to the slot.

    假设当前有4个slot连接到QPushButton::clicked(bool),当按钮被按下时,QT就把这个signal包装成一个QEvent,放到消息队列里。QApplication::exec()或者线程的QThread::exec()会从消息队列里取消息,然后调用signal关联的几个slot。这种方式既可以在线程内传递消息,也可以跨线程传递消息。

  • Qt::BlockingQueuedConnection

    Same as QueuedConnection, except that the current thread blocks until the slot has been delivered. This connection type should only be used for receivers in a different thread. Note that misuse of this type can lead to dead locks in your application.

    Qt::QueuedConnection类似,但是会阻塞等到关联的slot都被执行。这里出现了阻塞这个词,说明它是专门用来多线程间传递消息的。

  • Qt::AutoConnection

    If the signal is emitted from the thread in which the receiving object lives, the slot is invoked directly, as with Qt::DirectConnection; otherwise the signal is queued, as with Qt::QueuedConnection.

    这种连接类型根据signal和slot是否在同一个线程里自动选择Qt::DirectConnectionQt::QueuedConnection

这样看来,第一种类型的效率肯定比第二种高,毕竟第二种方式需要将消息存储到队列,而且可能会涉及到大对象的复制(考虑sig_produced(BigObject bo)这个slot,bo需要复制到队列里)。

与wxWidget、MFC的效率比较

wxWidget没用过,了解过MFC。我觉得MFC的消息队列是比较简单的,一般只是传递long数值、HANDLE、指针,效率上应该会比QT的队列方式高,然而QT的灵活性是MFC没办法比拟的,我还是比较喜欢QT这样的。

ps:被cppgx批表达不够准确,修改了一下。

标题无“转载”即原创文章,版权所有。转载请注明来源:http://hgoldfish.com/blogs/article/41/。


暂时还没有任何评论。


何不来发表一下您对本文的看法(使用Markdown语法,分段空两行):