2012-03-21 807 views
22

Qt的documentation说,它是可能的两个信号连接到一起的两个信号:Qt的连接在一起使用QueuedConnection

到的信号直接连接到另一信号甚至可以。

我尝试:

connect(x, SIGNAL(S()), y, SIGNAL(func())); 

和它的工作原理如前所述,但Qt文档继续:(这将立即发射所述第二信号时所述第一发射)

这是否意味着QueuedConnection将无法正常工作?我可以通过线程连接两个信号吗?

我问这个问题的原因是因为我通过避免这样解决了应用程序中的一类崩溃问题,但我不确定这是否与连接信号有关。

+2

您是否尝试过创建跨线程的信号,信号连接的测试案例?在原始信号之前和之后(在一个线程中)以及在连接到第二个信号(在第二个线程中)的插槽中打印消息。在第二个线程中,重复调用一个在事件循环中持续一两秒钟的“sleep”,以更明显地看到该线程中的插槽或者与第一个线程同步调用,或者在第二个线程中异步调用。 – tmpearce 2012-03-21 04:22:41

+0

@ tmpearce-好的建议,我会尝试一下并在此发布结果 – dashesy 2012-03-21 14:47:56

+2

那么,你有没有尝试过? – gnovice 2013-02-12 18:40:13

回答

24

它不应该和信号/插槽连接有很大区别。我们来看看信号/插槽的基本机制。每个线程中都有一个事件队列,用于维护已发出但尚未处理的信号(事件)。所以只要执行返回到事件循环,队列就被处理。事件循环本身不处理事件。相反,它将它们传递给对象,以便它们可以处理它。在这种特殊情况下,我想对象会发出另一个插入队列的信号。当执行返回到事件循环时,新的信号再次由对象处理。这是一个证明上述观点的测试。

如果运行附加的码,输出将是:

before signal() 
after signal() 
slot() called 

这意味着限定信号 - 信号连接类型,线程之间排队已预期的排队行为,即拒绝该参数,它总是即时。如果将其定义为直接输出,则输出如下:

before signal() 
slot() called 
after signal() 

如预期的那样。它不会产生任何错误或警告,程序也不会崩溃。但是,这个简单的例子并不能证明它适用于一个庞大而复杂的例子。

main.cpp中:

#include <QtGui/QApplication> 
#include "dialog.h" 
#include "testssconnection.h" 

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 

    TestSignalSignalConnection * t = new TestSignalSignalConnection(); 
    t->start(); 

    return a.exec(); 
} 

testssconnection.h:

#ifndef TESTSSCONNECTION_H 
#define TESTSSCONNECTION_H 

#include <QObject> 
#include <QThread> 

class TestSignalSignalConnection : public QThread 
{ 
    Q_OBJECT 
public: 
    explicit TestSignalSignalConnection(QObject *parent = 0); 

    void run(); 

signals: 
    void signal1(); 
    void signal2(); 

public slots: 
    void slot(); 
}; 

#endif // TESTSSCONNECTION_H 

testssconnection.cpp:

#include "testssconnection.h" 
#include <QtCore> 

TestSignalSignalConnection::TestSignalSignalConnection(QObject *parent) : 
    QThread(parent) 
{ 
} 

void TestSignalSignalConnection::run() 
{ 
    TestSignalSignalConnection *t = new TestSignalSignalConnection(); 

    this->connect(this,SIGNAL(signal1()),t,SIGNAL(signal2()), Qt::QueuedConnection); 
    t->connect(t,SIGNAL(signal2()), t,SLOT(slot()), Qt::DirectConnection); 

    qDebug() << "before signal()"; 
    emit signal1(); 
    qDebug() << "after signal()"; 

    exec(); 
} 

void TestSignalSignalConnection::slot() 
{ 
    qDebug() << "slot() called"; 
}