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