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 <QThread>

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 <QDebug>
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 <QString>
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 <QtWidgets/QMainWindow>
#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

  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wb175208

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值