QT中信号槽的连接方式有五种:
Qt::AutoConnection
信号槽默认的连接方式,如果信号与槽在同一线程,就自动采用Qt::DirectConnection,
如果信号与槽不在同一线程,将自动采用Qt::QueuedConnection的连接方式。
Qt::DirectConnection
Qt::DirectConnection表示一旦信号产生,立即执行槽函数。 (如果主线程发送信号给子线程,则这个参数要使用 Qt::DirectConnection ,槽函数在子线程中立即执行)
Qt::QueuedConnection
在不同的线程中处理, Qt::QueuedConnection表示将发送信号给接受线程,并且进入接收线程的队列,等候处理,像是Win32中PostMessage
Qt::BlockingQueuedConnection
在不同的线程中处理,当前线程信号发送后,会阻塞等待,接收线程处理完成后才会返回,发送线程会进行下一步的处理 。
但是如果在一个线程中使用这种信号槽的连接方式,会是怎么样的呢?
在运行的时候,程序会一直卡在发送信号的地方,并不会报错但是,会输出一下信息:
Qt: Dead lock detected while activating a BlockingQueuedConnection: Sender is QtManager(0xfc3f8c3a40), receiver is QtManager(0xfc3f8c3a40)
出现了死锁现象。
信号槽的连接可以在在一个地方,但是发送信号的地方和槽函数的地方必须在两个线程中才可以
Qt::UniqueConnection
Qt::UniqueConnection表示只有它不是一个重复连接,连接才会成功。如果之前已经有了一个链接(相同的信号连接到同一对象的同一个槽上),那么连接将会失败并将返回false。
例如:
#pragma once
#include
class MyThread : public QThread {
Q_OBJECT
public:
MyThread(QObject *parent);
~MyThread();
void run()override;
private:
int _count = 0;
};
#include "MyThread.h"
#include "QtManager.h"
#include
MyThread::MyThread(QObject *parent)
: QThread(parent) {
}
MyThread::~MyThread() {
}
void MyThread::run() {
while (true) {
msleep(800);
_count++;
Mgr()->setTextInThread(QString::number(_count));
qDebug() << QString("MyThread:%1").arg(_count);
}
}
#pragma once
#include
class IText {
public:
IText();
~IText();
virtual void setText(QString t);
};
#include "IText.h"
IText::IText() {
}
IText::~IText() {
}
void IText::setText(QString t) {
}
#pragma once
#include
#include "ui_QtGuiThread.h"
#include "IText.h"
class MyThread;
class QtGuiThread : public QMainWindow ,public IText {
Q_OBJECT
public:
QtGuiThread(QWidget *parent = Q_NULLPTR);
virtual void setText(QString t)override;
private:
void init();
private slots:
void slotStart();
private:
Ui::QtGuiThreadClass ui;
MyThread* _myThread = nullptr;
};
#include "QtGuiThread.h"
#include "MyThread.h"
#include "QtManager.h"
QtGuiThread::QtGuiThread(QWidget *parent)
: QMainWindow(parent) {
ui.setupUi(this);
init();
}
void QtGuiThread::setText(QString t) {
ui.lineEdit->setText(t);
}
void QtGuiThread::init() {
Mgr()->setIText(this);
connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(slotStart()));
_myThread = new MyThread(nullptr);
}
void QtGuiThread::slotStart() {
_myThread->start();
}
aaa