Qt 在线程中invokeMethod采用QueuedConnection模式,调用带指针参数槽,实际不会调用

widgetObject有操函数Test:

void Test(int *v);

在线程中调用Test,会被忽略,实际不会调用。

QMetaObject::invokeMethod(widgetObject, "Test", Qt::QueuedConnection, Q_ARG(int*,&v));

下面是网上找的理由: 

1.在同一个线程中
当信号和槽都在同一个线程中时,值传递参数和引用传递参数有区别: 值传递会复制对象;(测试时,打印传递前后的地址不同) 引用传递不会复制对象;(测试时,打印传递前后的地址相同)

不在同一个线程中
当信号和槽不在同一个线程中时,分两种情况。 1、connect时使用AutoConnection(跨线程默认是QueuedConnection):值传递参数和引用传递参数没有区别,都会复制对象;(测试时,打印传递前后的地址不同) 2、connect时使用DirectConnection,测试结果和在同一线程中的结果相同。

2.emit发射信号 在信号中以&引用作为参数
以引用作为参数一定要注意,在第二次发射信号的时候,引用的实体已经不存在了。

所以,如果想让每一次发射的信号中参数的值都保存下来,不能是&引用和*指针作为参数,而应该使用值传递。

这样每次发射信号的值都能够保存下来。

3.当我们传递一些自定义类型,比如类和结构体的时候,传递可能会出错,自己亲身体会,看到自己的信号槽已经关联了但是信号发出之后根本不会进入槽函数,因为这个信号槽是无效的,因为你自己定义的类型没有注册的话,信号槽机制将无法识别,解决办法就是进行如下操作进行注册

 

方法一:先把指针封装到struct中,在使用qRegisterMetaType注册struct类型,来传递

方法二:懒人办法,把指针转地址换为long long,通过long long参数传递

posted @ 2023-08-04 10:47  上位机  阅读(214)  评论(0编辑  收藏  举报