信号发送,槽函数执行,过程中传递的是对象的引用,涉及的拷贝操作

该博客探讨了Qt框架中信号和槽机制在跨线程传递对象引用时的对象拷贝行为。通过实例展示了当使用Qt::QueuedConnection时,对象会在消息队列中进行拷贝,而使用Qt::DirectConnection则避免了拷贝。文章还详细记录了对象生命周期和线程间的交互过程,揭示了Qt事件循环对数据传递的影响。
摘要由CSDN通过智能技术生成

如果qt的信号和槽之间发送的是对象的引用,传递过程中会发生拷贝操作。
一、跨线程之间

#ifndef __MAIN_WINDOW_H_
#define __MAIN_WINDOW_H_

#include <QMainWindow>
#include <QThread>
#include <QPushButton>
#include "InheritObject.h"

class MainWindow:public QMainWindow
{
	Q_OBJECT
public:
	explicit MainWindow(QWidget *parent = 0);
private slots:
	void on_sendObjectRef_clicked();
	
signals:
	void sendObjectRef(MyObject&);
private:
	QThread *m_th;
	InheritObject *m_obj;
	void InitUi();
};

#endif __MAIN_WINDOW_H_

#include "MainWindow.h"
#include <QGridLayout>
#include <QDebug>
#include "MyObject.h"

MainWindow::MainWindow(QWidget *parent):QMainWindow(parent)
{
	qDebug()<<"GUI thread = "<<QThread::currentThreadId();
	InitUi();
	m_th = new QThread();
	m_obj = new InheritObject();
	m_obj->moveToThread(m_th);
	connect(this,&MainWindow::sendObjectRef,m_obj,&InheritObject::onReceiveObjectRef);

	//启动线程,线程默认开启事件循环,并且线程正处于事件循环状态
	m_th->start();
}

void MainWindow::InitUi()
{
	QWidget *pWidget = new QWidget(this);
	QGridLayout *pLayout = new QGridLayout();
	QPushButton *pSendObjectRef = new QPushButton("SendObjectRef",this);
	pLayout->addWidget(pSendObjectRef ,0,0);
    connect(pSendObjectRef ,&QPushButton::clicked,this,&MainWindow::on_sendObjectRef_clicked);
	
	pWidget->setLayout(pLayout);
	this->setCentralWidget(pWidget);
}


void MainWindow::on_sendObjectRef_clicked()
{
	MyObject myObject;
	myObject.age = 23;
	myObject.name = "wangjian";
	emit sendObjectRef(myObject);
}

#ifndef __INHERIT_OBJECT_H_
#define __INHERIT_OBJECT_H_
#include <QObject>
#include "MyObject.h"

class InheritObject:public QObject
{
	Q_OBJECT
public:
	explicit InheritObject(QObject *parent = 0);
	
public slots:
	void onReceiveObjectRef(MyObject object&);
};

#endif

#include "InheritObject.h"
#include <QDebug>
#include <QThread>

InheritObject::InheritObject(QObject *parent):QObject(parent)
{
	
}

void InheritObject::onReceiveObjectRef(MyObject object&)
{
	qDebug()<<(QString(" %1 %2 ").arg(object.age).arg(object.name));
}

#ifndef __MY_OBJECT_H_
#define __MY_OBJECT_H_
#include <QObject>
#include <QDebug>
#include <QThread>
class MyObject
{

public:
	MyObject()
	{
		qDebug()<<"function  "<<__FUNCTION__<<this<<QThread::currentThreadId();
	}
	
	MyObject(const MyObject& object)
	{
		qDebug()<<"function  copy "<<__FUNCTION__<<this<<QThread::currentThreadId();
		this->age = object.age;
		this->name = object.name;
	}
	~MyObject()
	{
		qDebug()<<"function  "<<__FUNCTION__<<this<<QThread::currentThreadId();
	}
	int age;
	QString name;	
};
#endif

#include <QApplication>
#include "MainWindow.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
	qRegisterMetaType<MyObject>("MyObject&");

	MainWindow w;
	w.show();
    return app.exec();
}

运行结果

GUI thread =  0x237c
function   MyObject::MyObject 0x3fbdefa288 0x237c //栈变量创建
function  copy  MyObject::MyObject 0x219623b4760 0x237c //发送信号后,并没有立即调用槽函数,放入到消息队列中,进行了拷贝
function   MyObject::~MyObject 0x3fbdefa288 0x237c//栈变量销毁
" 23 wanggang "
function   MyObject::~MyObject 0x219623b4760 0x29b4//槽函数执行完后,消息队列中的对象销毁

二、在同一个线程
改一下connect的最后一个连接参数,由自动改为Qt::DirectConnection

connect(this,&MainWindow::sendObjectRef,m_obj,&InheritObject::onReceiveObjectRef);
改为
connect(this,&MainWindow::sendObjectRef,m_obj,&InheritObject::onReceiveObjectRef,Qt::DirectConnection);

运行结果

GUI thread =  0x2200
function   MyObject::MyObject 0x3b4e4fa7f8 0x2200//栈变量创建
" 23 wanggang "
function   MyObject::~MyObject 0x3b4e4fa7f8 0x2200//栈变量销毁

结论

Qt::DirectConnection的连接方式,槽函数直接被调用,不会发生对象拷贝
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值