QToolButton内存提前释放导致mouseReleaseEvent崩溃问题
1、问题现象及原因分析
1.1、问题现象
如图所示,mouseReleaseEvent接口this指针地址为空,导致了Qt内部发生了Access violation异常。
1.2、问题原因
在项目中,使用该QToolButton作为关闭按钮;对应的槽函数用来释放页面的所有资源包括该QToolButton的资源。从而导致了QToolButton的资源已经被释放,而mouseReleaseEvent还在处理鼠标释放的事件,而引发的崩溃;
2、mouseReleaseEvent事件、released信号以及clicked信号对应的槽函数执行顺序
使用demo程序发现
处理的顺序为mouseReleaseEvent -> released信号 -> clicked信号
按道理说,永远不应该出现上面描述的问题,因为mouseReleaseEvent应该在released信号槽函数执行之前就已经执行了。但是,但是,但是,谁先执行完成就不知道了,我们添加一下执行结束的日志发现
mouseReleaseEvent执行完成可能比released槽函数晚,这就有可能在槽函数中释放了QToolButton的内存但是mouseReleaseEvent还未执行完成的情况。这也是我们程序中低概率出现崩溃的原因。
3、解决方案
我们采用在connect连接函数最后添加Qt::QueuedConnection选项,使槽函数在下一个事件循环(event loop)中被调用,而不是立即调用避免先释放资源后执行mouseReleaseEvent的情况。