如果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的连接方式,槽函数直接被调用,不会发生对象拷贝