1、Qt::AutoConnection: 默认值,使用这个值则连接类型会在信号发送时决定。如果接收者和发送者在同一个线程,则自动使用Qt::DirectConnection类型。如果接收者和发送者不在一个线程,则自动使用Qt::QueuedConnection类型。
2、Qt::DirectConnection:槽函数会在信号发送的时候直接被调用,槽函数运行于信号发送者所在线程。效果看上去就像是直接在信号发送位置调用了槽函数。这个在多线程环境下比较危险,可能会造成奔溃。
3、Qt::QueuedConnection:槽函数在控制回到接收者所在线程的事件循环时被调用,槽函数运行于信号接收者所在线程。发送信号之后,槽函数不会立刻被调用,等到接收者的当前函数执行完,进入事件循环之后,槽函数才会被调用。多线程环境下一般用这个。
4、Qt::BlockingQueuedConnection:槽函数的调用时机与Qt::QueuedConnection一致,不过发送完信号后发送者所在线程会阻塞,直到槽函数运行完。接收者和发送者绝对不能在一个线程,否则程序会死锁。在多线程间需要同步的场合可能需要这个。
5、Qt::UniqueConnection:这个flag可以通过按位或(|)与以上四个结合在一起使用。当这个flag设置时,当某个信号和槽已经连接时,再进行重复的连接就会失败。也就是避免了重复连接。
1 static EventLoop* gEventLoop = nullptr; 2 3 void FFF() 4 { 5 gEventLoop = new EventLoop(); 6 } 7 8 MainWindow::MainWindow(QWidget *parent) : 9 QMainWindow(parent), 10 ui(new Ui::MainWindow) 11 { 12 ui->setupUi(this); 13 14 std::thread ttt(FFF); //另一个线程中创建对象 15 ttt.join(); 16 17 connect(this, &MainWindow::Call, eLoop, &EventLoop::Called, Qt::QueuedConnection); //连接成功 槽函数不执行 18 connect(eLoop, &EventLoop::eee, this, &MainWindow::HHH, Qt::QueuedConnection); 19 20 }
connect(this, &MainWindow::Call, eLoop, &EventLoop::Called, Qt::QueuedConnection); //连接成功 槽函数不执行
这里因为发送信号的对象和接收信号的对象不在同一个线程,使用QueueConnection,但是发送信号后 槽函数不会执行。
信号发送成功后,会把信号放到接收对象所在线程的事件循环队列,排到它的时候,自动调用槽函数。
但是std::thread创建的线程中,没有事件循环,所以没有接收到信号,槽函数不会执行。
1.为线程创建一个事件循环。(不会。。。)
2.使用QThread开启线程,QThread自带默认事件循环。
1 MainWindow::MainWindow(QWidget *parent) : 2 QMainWindow(parent), 3 ui(new Ui::MainWindow) 4 { 5 ui->setupUi(this); 6 7 // std::thread ttt(FFF); //另一个线程中创建对象 8 // ttt.join(); 9 10 // connect(this, &MainWindow::Call, eLoop, &EventLoop::Called, Qt::QueuedConnection); //连接成功 槽函数不执行 11 // connect(eLoop, &EventLoop::eee, this, &MainWindow::HHH, Qt::QueuedConnection); 12 13 qThread = new QThread(); 14 eLoop = new EventLoop(); 15 eLoop->moveToThread(qThread); 16 17 connect(qThread, &QThread::finished, eLoop, &QObject::deleteLater); 18 connect(qThread, &QThread::finished, qThread, &QObject::deleteLater); 19 connect(qThread, &QThread::destroyed, [=](){qThread = nullptr;}); 20 connect(eLoop, &QThread::destroyed, [=](){eLoop = nullptr;}); 21 22 connect(this, &MainWindow::Call, eLoop, &EventLoop::Called, Qt::QueuedConnection); 23 connect(eLoop, &EventLoop::eee, this, &MainWindow::HHH, Qt::QueuedConnection); 24 // QObject::connect(eLoop, &EventLoop::eee, this, &MainWindow::HHH, Qt::QueuedConnection); 25 qThread->start(); 26 }
qThread = new QThread();
eLoop = new EventLoop(); //创建对象
eLoop->moveToThread(qThread); //把对象放到线程中执行,此时线程自带事件循环,发送信号,槽函数能正确调用。(参考 https://www.huaweicloud.com/articles/2a9c964f7ee0900f9bd029224b9f2b26.html)
深入理解-》 Qt信号槽机制源码解析
原文:https://www.cnblogs.com/linxisuo/p/13448239.html