Qt信号槽函数没有响应问题

文章讲述了在QT程序中,作者遇到uint16_t类型信号槽通信问题,通过尝试Block连接、修改参数类型和注册元类型,最终解决了槽函数响应延迟的问题。同时探讨了为何不需注册uint16_t即可使用BlockingQueuedConnection的原因。
摘要由CSDN通过智能技术生成

问题描述:

QT程序中通过信号槽函数实现组件间通信。我自己写的信号槽函数,信号函数在read线程,槽函数在主线程。函数的参数类型是uint16_t。通过如下方式连接信号槽,发现信号函数被调用后槽函数无法响应。 

connect(this, SIGNAL(SignalFileTransUpdate(uint16_t)), this, SLOT(SlotFileTransUpdate(uint16_t)));

参数类型为uint16_t

连接类型为默认类型

测试结果: 槽函数无响应

问题解决:

方案1: 使用Block连接类型

搜了网上资料,可能是槽函数操作耗时,可以设置连接类型为Qt::BlockingQueuedConnection。设置之后槽函数确实可以响应。

connect(this, SIGNAL(SignalFileTransUpdate(uint16_t)), this, SLOT(SlotFileTransUpdate(uint16_t)), Qt::BlockingQueuedConnection);

参数类型为uint16_t

连接类型为Qt::BlockingQueuedConnection

测试结果: 槽函数响应正常

但是Qt::BlockingQueuedConnection连接类型会导致信号函数所在线程必须等待槽函数执行完才会继续执行,会严重影响执行效率。

方案2:修改函数参数

看到别的说法,可能是信号槽函数所在线程没有在事件循环中。尝试调用别的信号槽函数(参数为int类型),发现调用ok。尝试修改参数类型为unsigned short。修改之后信号槽函数响应ok。

connect(this, SIGNAL(SignalFileTransUpdate(unsigned short)), this, SLOT(SlotFileTransUpdate(unsigned short)));

参数类型为unsigned short

连接类型为默认类型

测试结果: 槽函数响应正常

方案3: 注册uint16_t到QT

使用unsigned short参数ok,使用uint16_t无法响应,所以应该是uint16_t参数类型问题,尝试注册uint16_t到qt,修改之后信号槽函数响应ok。

qRegisterMetaType<uint16_t>("uint16_t");
connect(this, SIGNAL(SignalFileTransUpdate(uint16_t)), this, SLOT(SlotFileTransUpdate(uint16_t)));

注册uint16_t参数类型到QT

参数类型为uint16_t

连接类型为默认类型

测试结果: 槽函数响应正常

疑问:

1. 为什么uint16_t需要注册才能使用,unsigned short可以直接使用?

unsigned short是c++标准数据类型,但是uint16_t是typedefine的类型。相当于自定义的数据类型。

2. 为什么不注册uint16_t,设置Qt::BlockingQueuedConnection连接类型槽函数也可以响应呢?

https://blog.csdn.net/weixin_42981623/article/details/108548379

参考上文,信号槽函数在连接的时候会有几步检查:

1. connect函数的参数检查

2. 获取信号和槽的index

3. 检查信号和槽的参数是否匹配

4. 检查信号参数类型

5. 创建连接对象

在以上检查中,如果连接类型是Qt::BlockingQueuedConnection,不需要检查参数类型。

因为虽然BlockingQueuedConnection是队列连接,但是通过阻塞变成了同步调用,所以不存在参数生命周期问题,所以不会去克隆信号参数,所以也就不需要是QMetaType。

  • 18
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt中,信号是一种用于对象间通信的机制。信号是对象发出的事件,而是对这些事件进行响应函数。当一个信号被触发时,与之相连接的函数将会被调用。 在Qt中,信号函数可以具有不同的参数类型。当信号函数的参数类型不匹配时,Qt会自动进行类型转换。但是,如果你需要传递额外的参数给函数,你可以使用信号函数指针参数。 具体来说,你可以在信号函数的定义中使用指针参数。当信号被触发时,可以通过指针参数传递额外的数据给函数。这样,函数就可以根据传递的数据进行相应的处理。 下面是一个示例代码,演示了如何在Qt中使用信号函数指针参数: ```cpp class MyObject : public QObject { Q_OBJECT public: MyObject(QObject *parent = nullptr) : QObject(parent) {} signals: void mySignal(int value, QString text); public slots: void mySlot(int value, QString text) { // 处理传递过来的参数 qDebug() << "Received value:" << value; qDebug() << "Received text:" << text; } }; int main(int argc, char *argv[]) { QApplication app(argc, argv); MyObject obj; // 连接信号函数 QObject::connect(&obj, &MyObject::mySignal, &obj, &MyObject::mySlot); // 触发信号,并传递参数 emit obj.mySignal(42, "Hello, world!"); return app.exec(); } ``` 在上面的示例中,`mySignal`信号带有两个参数:一个整数和一个字符串。`mySlot`函数也带有相同的参数。通过使用信号函数指针参数,我们可以将信号的参数传递给函数进行处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值