0
点赞
收藏
分享

微信扫一扫

Qt多线程之间传递参数

互联网码农 2022-01-13 阅读 122
connect(this, SIGNAL(ReceiveThread(void*,int,int)), receiveInfo, SLOT(doReceiveTh(void*,int,int)));
    connect(&receiveThread, SIGNAL(finished()),receiveInfo, SLOT(deleteLater()));

在主线程做以上操作。

上面中ReceiveThread(void*,int,int)是定义的主线程信号,若是要给子线程传递参数就使用emit直接发送信号给子线程。doReceiveTh(void*,int,int)是子线程须要执行的函数。

多线程间须要传递信号给另一个线程的槽,而信号和槽所使用的参数为非QObject,不管其是stl的标准库类型仍是其余类型,都必须先注册,不然信号发送了,槽将会始终不调用。也就是说qt的槽参数必定要是QOject类型的参数(QObject类的子类型也是QObject类型)安全

注册方式如下:

#include <QMetaType>  //该文件为qRegisterMetaType所在头文件,也可使用 #include <QtGui>此头文件包括了全部的qt类型头文件异步

qRegisterMetaType<type>("type");

如我须要传递一个stl的map类型,则需在链接信号和槽以前先注册这个map类型

qRegisterMetaType<std::map<std::string,AppInfo>>("std::map<std::string,AppInfo>");  //AppInfo为自定义的一个类型ui

connect(cfThread,SIGNAL(SetInfo(const map<string,AppInfo>&)),this,SLOT(ShowConfig(const map<string,AppInfo>&));

也能够用如下这种方法,不过此法不安全:

使用connect的第5个参数,将默认的Qt::AutoConnection改成Qt::DirectConnection,也能成功调用槽函数。可是此法不安全。

一般使用的connect,实际上最后一个参数使用的是Qt::AutoConnection类型:

bool QObject::connect ( const QObject * sender, const char * signal, const QObject * receiver, const char * method,Qt::ConnectionType type = Qt::AutoConnection )

Qt支持6种链接方式,其中3种最主要的方式如下:

  • Qt::DirectConnection(直连方式)

      当信号发出后,相应的槽函数将当即被调用。emit语句后的代码将在全部槽函数执行完毕后被执行。(信号与槽函数关系相似于函数调用,同步执行)

  • Qt::QueuedConnection(排队方式)

      当信号发出后,排队到信号队列中,需等到接收对象所属线程的事件循环取得控制权时才取得该信号,调用相应的槽函数。emit语句后的代码将在发出信号后当即被执行,无需等待槽函数执行完毕。(此时信号被塞到信号队列里了,信号与槽函数关系相似于消息通讯,异步执行)

  • Qt::AutoConnection(自动方式)

      Qt的默认链接方式,若是信号的发出和接收这个信号的对象同属一个线程,那么工作方式与直连方式相同;不然工作方式与排队方式相同。

即便用排队方式的信号-槽机制,Qt的元对象系统(meta-object system)必须知道信号传递的参数类型。这里手动改成直连方式,Qt的元对象系统就没必要知道参数类型了,因而警告信息消失。但这样作是不安全的,见Qt官方文档:

总结: 

解决方法有两种:

1、把本身定义的类型注册为元组类型,使用qRegisterMetaType()注册,要把这个函数放在connect()函数使用以前。

参考代码:

#include <QMetaType>//记得包含这个头文件
//my_type是我本身定义的类型
qRegisterMetaType<my_type>("my_type");
connect(xx,SIGNAL(xx(my_type)),xx,SLOT(xx(my_type)));

2、在connect函数的第五个参数加入Qt::DirectConnection

connect(xx,SIGNAL(xx(my_type)),xx,SLOT(xx(my_type)),Qt::DirectConnection);
举报

相关推荐

0 条评论