它与信号/插槽连接应该没有太大区别。让我们看一下信号/槽的底层机制。每个线程中都有一个事件队列,用于维护已发出但尚未处理的信号(事件)。因此,只要执行返回到事件循环,就会处理队列。事件循环本身不处理事件。相反,它将它们传递给对象,以便它们可以处理它。在这种特殊情况下,我假设对象会发出另一个信号,该信号将插入队列中。当执行返回到事件循环时,新信号再次由对象处理。这是一个证明上述论点的测试。
如果您运行附加的代码,输出将是:
before signal()
after signal()
slot() called
这意味着将信号-信号连接类型定义为在线程之间排队具有预期的排队行为,这拒绝了它总是立即的参数。如果将其定义为直接,则输出将是:
before signal()
slot() called
after signal()
正如预期的那样。它不会产生任何错误或警告,程序也不会崩溃。然而,这个简单的例子并不能证明它也适用于大型复杂的例子。
主.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();
}
测试连接.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
测试连接.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";
}