QT信号槽连接之不同线程之间的信号槽连接方式

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

你可能感兴趣的:(qt,信号槽,不同的线程)