Qt信号与槽

在Qt的开发中核心之一就是信号与槽的设计,它们的具体概念我就不多叙述了,可以看看IBM的这篇文章讲的很清楚——《Qt的信号与槽机制介绍》。有一些Windows开发经验的角度来看,信号与槽机制就像windows的消息机制,发射消息就是相当于像操作系统发送消息,槽函数的实现就相当于消息响应函数的实现,当然,Qt中是一个线程实现的传递,而在windows中则是操作系统实现的。

今天我不详细讲解一下信号与槽的具体用法,只是说明一下在用法上的一个误区,网上很多文章对它的简单用法的说明,比如《Qt的信号与槽机制介绍》这篇文章上,对信号的声明:

signals: 
		 void mySignal(); 
		 void mySignal(int x); 
		 void mySignalParam(int x,int y);
对槽函数的声明:

public slots: 
		 void mySlot(); 
		 void mySlot(int x); 
		 void mySignalParam(int x,int y);

再把信号和槽连接起来就能完成,最后对槽函数实现一下就OK。

但是如果信号与槽传递的是我们自定义的类型或者是非基本类型呢?比如说是QVector容器等数据。很多人就会说了,那我把它们作为形参传递进来不久OK了,下面我们试一下。

class RecognitionData 
{
private:QImage* m_recogImage;QString m_recogAngle;}

这是一个简单的自定义类型,我们先实例化一个对象,然后声明以它作为形参的信号与槽,最后把信号与槽连接起来。

RecognitionData data();
signals:
          void mySignal(RecognitionData);
public slots:
           void mySloy(RecognitionData);
但是当我们发射这个信号的时候却发现槽函数根本没有响应,这是为什么呢?

我当时遇到这个问题之后就得是不是声明和使用有问题,因为在连接信号与槽的时候,编译器不会检查是否存在这个信号与槽。很认真的检查了几遍之后发现没有错,那这是为什么呢?当时很不明白,纠结了很长时间,网上也没有说法。

最后我抱着试试的态度,把信号和槽的参数设置为自定义类或者是非基本类型的指针,比如:

RecognitionData data();
signals:
          void mySignal(RecognitionData *);
public slots:
           void mySloy(RecognitionData *);

 奇迹发生了,槽函数居然进行了响应,这样我就得到了一个结论,信号与槽传递时只能传递最基本的类型或者是指针,但是想想为什么会有这么个限制呢,难道Qt的设计团队没有想到这个问题,显然不可能。

仔细想想整个流程发现,如果将实例化的对象作为信号和槽的形参传递,在槽函数还没开始执行的时候,传递的这个实例化的对象已经在发射信号之后销毁了,槽函数就没法访问到这个对象,那它怎么可能会执行呢?原来如此啊!

但是指针为什么能行呢?这就是指针跟实例对象的区别,指针指向的内存块是在堆内存中,不手动销毁的话程序是不会自动销毁的,而实例化的对象则不一样,它是在栈中实例化的,在它的作用域结束之后,程序会自动将它销毁掉。

终于弄明白了以上的问题,感慨啊,一个小小的问题还涉及到这么多机制,值得说明的是,如果以指针作为形参传递的话,在槽函数中一定要去释放这个指针指向的内存,否则就会出现内存泄露。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值