Qt工作笔记-对connect的第五个参数的研究

标签: C  Qt

本程序配合了QObject::sender,关于QObject::sender在下面这个链接中:

https://blog.csdn.net/qq78442761/article/details/81916570

 

元素程序源码如下:

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include 

class Worker;

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

public slots:
    void receiveBuffer(QString msg);

private:
    Ui::Widget *ui;
    Worker *m_worker[3];
};

#endif // WIDGET_H

worker.h

#ifndef WORKER_H
#define WORKER_H

#include 

class Worker : public QThread
{
    Q_OBJECT
public:
    explicit Worker(QObject *parent = 0);
    ~Worker();

    void create(const QString flag,const int delayTime);
    void destroy();

signals:
    void senderBuffer(QString msg);

private:
    QString m_flag;
    int m_delayTime;
    void run();
};

#endif // WORKER_H

main.cpp

#include "widget.h"
#include 

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

widget.cpp

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

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    for(int i=0;i<3;i++){
        m_worker[i]=new Worker;
        connect(m_worker[i],SIGNAL(senderBuffer(QString)),this,SLOT(receiveBuffer(QString)));
    }

    m_worker[0]->create("FIRST",300);
    m_worker[1]->create("SECOND",400);
    m_worker[2]->create("THIRD",500);
}

Widget::~Widget()
{
    m_worker[0]->destroy();
    m_worker[1]->destroy();
    m_worker[2]->destroy();
    delete ui;
}

void Widget::receiveBuffer(QString msg)
{
    QListWidgetItem *item=new QListWidgetItem;
    msg.append(" The QObject::sender is "+QString::number((uint)QObject::sender(),16)+" !");
    item->setText(msg);
    ui->listWidget->insertItem(0,item);
    if(msg.contains("FIRST")){
        item->setTextColor(Qt::red);
    }
    else if(msg.contains("SECOND")){
        item->setTextColor(Qt::green);
    }
    else{
        item->setTextColor(Qt::blue);
    }
}

worker.cpp

#include "worker.h"
#include 

Worker::Worker(QObject *parent) : QThread(parent)
{

}

Worker::~Worker()
{

}

void Worker::create(const QString flag, const int delayTime)
{
    m_flag=flag;
    m_delayTime=delayTime;
    start();
}

void Worker::destroy()
{
    wait();
}

void Worker::run()
{
    while(1){
        QThread::msleep(m_delayTime);
        senderBuffer("The pointer address is "+QString::number((uint)this,16)+" . My flag is "+m_flag+" !");
    }
}

原始程序运行截图如下:

 

这里来看Qt中connect的第五个参数,很有意思:

一个个来分析把:

Qt::AutoConnection:这个是默认的参数,当发送信号和接收信号的在一个线程里面的时候会直接相连接;跨线程用Qt::QueuedConnection,用一个队列,进行处理(设计得真J8溜)

Qt::DirectConnection:在同一线程的时候直接相连,因为在一个线程里面并不会出现资源短缺,强占等问题;

Qt::QueuedConnection:这个参数和socket里面的listen的第二个参数极其相似(估计是大佬都会想到一个地方),

关于listen第二个参数的意义看这个博文:

https://blog.csdn.net/qq78442761/article/details/72917408

感觉QueuedConnection和这个差不多,就和打电话一样。

下面两个参数就和字面上描述的那样。

有的时候,我们鼠标点击一下会调2次函数,可以用UniqueConnection解决这个问题

 

因为是跨线程,把connect最后一个参数设置为Qt::DirectConnection看看QObject::sender会不会返回0

关键代码如下:

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    for(int i=0;i<3;i++){
        m_worker[i]=new Worker;
        connect(m_worker[i],SIGNAL(senderBuffer(QString)),this,SLOT(receiveBuffer(QString)),Qt::DirectConnection);
    }

    m_worker[0]->create("FIRST",300);
    m_worker[1]->create("SECOND",400);
    m_worker[2]->create("THIRD",500);
}

程序运行截图如下:

果然如此:

QObject::sender感觉Qt不太喜欢我们用这个函数,不然在此线程调用另外一个线程的东西,这样容易出现问题!!!

原文链接:加载失败,请重新获取