信号与槽的连接方式
我们查看文档时,发现connect函数还有第五个参数。那么这个参数的作用是什么呢?我们之前使用的是默认值,具体的功能是什么呢?
知识回顾
-
每一个线程都有自己的事件队列
-
线程通过事件队列接收信号
-
信号在事件循环中被处理
示例代码:信号与槽的连接方式
//MyObject.h
class MyObject : public QObject
{
Q_OBJECT
public:
explicit MyObject(QObject *parent = 0);
signals:
protected slots:
void testSlot();
};
//MyObject.cpp
void MyObject::testSlot()
{
qDebug() << "void MyObject::testSlot() tid = " << QThread::currentThreadId();
}
//MyThread.h
class TestThread : public QThread
{
Q_OBJECT
protected:
void run();
public:
explicit TestThread(QObject *parent = 0);
signals:
void testSignal();
};
//MyThread.cpp
void TestThread::run()
{
qDebug() << "void TestThread::run() -- begin tid = " << currentThreadId();
for(int i=0; i<3; i++)
{
qDebug() << "void TestThread::run() i = " << i;
sleep(1);
}
emit testSignal();
exec();
qDebug() << "void TestThread::run() -- end";
}
Qt::DirectConnection(立即调用)
直接在发送信号的线程中调用槽函数,等价于槽函数的实时调用!
示例代码:信号与槽的直接调用
void direct_connection()
{
static TestThread t;
static MyObject m;
QObject::connect(&t, SIGNAL(testSignal()), &m, SLOT(testSlot()), Qt::DirectConnection);
t.start();
t.wait(5 * 1000);
t.quit();
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug() << "main() tid = " << QThread::currentThreadId();
direct_connection();
return a.exec();
}
输出结果:
main() tid = 0x2ff4
void TestThread::run() – begin tid = 0x1d98
void TestThread::run() i = 0
void TestThread::run() i = 1
void TestThread::run() i = 2
void MyObject::testSlot() tid = 0x1d98
void TestThread::run() – end
我们可以发现,当线程发送信号时,便立即调用了槽函数。接着才退出线程。
Qt::QueuedConnection(异步调用)
信号发送至目标线程的事件队列,由目标线程处理;当前线程继续向下执行
示例代码:信号与槽的异步调用
void queued_connection()
{
static TestThread t;
static MyObject m;
QObject::connect(&t, SIGNAL(testSignal()), &m, SLOT(testSlot()), Qt::QueuedConnection);
t.start();
t.wait(5 * 1000);
t.quit();
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug() << "main() tid = " << QThread::currentThreadId();
queued_connection();
return a.exec();
}
输出结果:
main() tid = 0x1fbc
void TestThread::run() – begin tid = 0x32f0
void TestThread::run() i = 0
void TestThread::run() i = 1
void TestThread::run() i = 2
void TestThread::run() – end
void MyObject::testSlot() tid = 0x1fbc
我们可以发现,当发送信号后,需要等待线程结束后再执行相应的槽函数。
Qt::BlockingQueuedConnection(同步调用)
信号发送至目标线程的事件队列,由目标线程处理;当前线程等待槽函数返回,之后继续向下执行!
注意:目标线程与当前线程必须不同
示例代码:信号与槽的同步调用
void blocking_queued_connection()
{
static TestThread t;
static MyObject m;
QObject::connect(&t, SIGNAL(testSignal()), &m, SLOT(testSlot()), Qt::BlockingQueuedConnection);
t.start();
t.wait(5 * 1000);
t.quit();
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug() << "main() tid = " << QThread::currentThreadId();
blocking_queued_connection();
return a.exec();
}
输出结果:
main() tid = 0x2554
void TestThread::run() – begin tid = 0x130
void TestThread::run() i = 0
void TestThread::run() i = 1
void TestThread::run() i = 2
void MyObject::testSlot() tid = 0x2554
void TestThread::run() – end
Qt::AutoConnection(默认连接)
[外链图片转存失败(img-C3e2HDf9-1563242662208)(/home/shangrongo/图片/Qt9.png)]
Qt::UniqueConnection(单一连接)
描述
- 功能与AutoConnection相同,自动确定连接类型
- 同一个信号与同一个槽函数之间只有一个连接
小知识
- 默认情况下,同一个信号可以多次连接到同一个槽函数
- 多次连接意味着同一个槽函数的多次调用