Qt::ConnectionType:Qt不同类型connect的详细区别说明与应用

ConnectionType

  • 一、介绍
    • 1.Qt::AutoConnection
    • 2.Qt::DirectConnection
    • 3.Qt::QueuedConnection
    • 4.Qt::BlockingQueuedConnection
    • 5.Qt::UniqueConnection
  • 二、场景
  • 三、测试
    • 1.声明
    • 2.实现
    • 3.输出
  • 四、结论

一、介绍

1.Qt::AutoConnection

默认连接类型,如果信号接收方与发送方在同一个线程,则使用Qt::DirectConnection,否则使用Qt::QueuedConnection;连接类型在信号发射时决定。

2.Qt::DirectConnection

信号所连接至的槽函数将会被立即执行,并且是在发射信号的线程;倘若槽函数执行的是耗时操作、信号由UI线程发射,则会阻塞Qt的事件循环,UI会进入无响应状态

3.Qt::QueuedConnection

槽函数将会在接收者的线程被执行,此种连接类型下的信号倘若被多次触发、相应的槽函数会在接收者的线程里被顺次执行相应次数;当使用QueuedConnection时,参数类型必须是Qt基本类型,或者使用qRegisterMetaType() 进行注册了的自定义类型

4.Qt::BlockingQueuedConnection

和Qt::QueuedConnection类似,区别在于发送信号的线程在槽函数执行完毕之前一直处于阻塞状态;收发双方必须不在同一线程,否则会导致死锁

5.Qt::UniqueConnection

可以搭配以上所有连接类型使用,一经设置之后,同一信号与同一槽函数的二次连接将会失败

二、场景

多线程中同一对象的不同槽函数,某个槽函数的执行依赖另一个槽函数的执行结果;可以将前一个槽函数的连接类型设置成DirectConnection,确保调用之后能被立即执行

三、测试

1.声明

#ifndef WIDGET_H
#define WIDGET_H

#include 
#include 
#include 
#include 

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class ThreadWorker : public QObject
{
    Q_OBJECT
public:
    ThreadWorker(QObject* parent);

public slots:
    void queuedConnect();
    void directConnect();
};

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    QVector<QThread*> listThread;
    QVector<ThreadWorker*> listWorker;
    Ui::Widget *ui;

private slots:
    void on_butDirect_clicked();
    void on_butQueued_clicked();
    void on_butAuto_clicked();

signals:
    void directConnect();
    void autoConnect();
    void queuedConnect();

};
#endif // WIDGET_H

2.实现

#include "widget.h"
#include "ui_widget.h"
#include 

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    for(int i = 0 ; i < 3 ; i++)
    {
        listThread.append(new QThread(this));
        listWorker.append(new ThreadWorker(nullptr));

    }

    connect(this,SIGNAL(directConnect()),listWorker[0],SLOT(directConnect()),Qt::DirectConnection);
    connect(this,SIGNAL(autoConnect()),listWorker[2],SLOT(directConnect()),Qt::AutoConnection);
    connect(this,SIGNAL(queuedConnect()),listWorker[1],SLOT(queuedConnect()),Qt::QueuedConnection);
    connect(this,SIGNAL(directConnect()),listWorker[1],SLOT(directConnect()),Qt::QueuedConnection);


    for(int  i = 0 ; i < 3 ; i++ )
        listWorker[i]->moveToThread(listThread[i]);

    for(auto i : listThread) i->start();
    qDebug()<<"The main thread id is "<< QThread::currentThreadId();

}

Widget::~Widget()
{
    delete ui;
    for(auto i : listThread)
        i->exit();
}

void Widget::on_butDirect_clicked()
{
    emit directConnect();
}

void Widget::on_butQueued_clicked()
{
    emit queuedConnect();
}

void Widget::on_butAuto_clicked()
{
    emit autoConnect();

}


ThreadWorker::ThreadWorker(QObject *parent) : QObject(parent)
{

}

void ThreadWorker::queuedConnect()
{
    for(int i  = 0 ; i <10 ; i ++)
        Sleep(100);
    qDebug()<<"The kid thread id is "<< QThread::currentThreadId();

}
void ThreadWorker::directConnect()
{
    for(int i  = 0 ; i <10 ; i ++)
        Sleep(100);
    qDebug()<<"The kid thread id is "<< QThread::currentThreadId();

}





3.输出

The main thread id is  0x30b0
The kid thread id is  0x30b0
The kid thread id is  0x7cc
The kid thread id is  0x7cc
The kid thread id is  0x24c0

四、结论

同一对象的不同槽函数可以有不同的连接类型,槽函数在哪个线程被执行由连接类型、信号发射时收发双方是否在一个线程决定

你可能感兴趣的:(Qt,#,Thread,qt,qt5,c++,多线程)