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

1 篇文章 0 订阅

一、介绍

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 <QWidget>
#include <QThread>
#include <QPushButton>
#include <windows.h>

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

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

四、结论

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

  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值