qmenu基本用法_点击右键弹出QMenu的使用问题。

目前来看QMenu的使用存在这几个问题。

1、如果使用了临时变量的QMenu,并且没有指定父窗体,例如:

QMenu menuDemo;

menuDemo.addAction(“test”);

menuDemo.exec();

那么会存在一个问题,就是如果使用某个快捷键将QMenu所在的Widget给关闭掉,QMenu并不会随着消失,这样子在流程上就存在着问题。

2、如果使用了临时变量的QMenu,并且指定父窗体,例如:

QMenu menuDemo(this);

menuDemo.addAction(“test”);

menuDemo.exec();

那么会存在一个问题,就是如果使用某个快捷键将QMenu所在的Widget给关闭掉,QMenu的父窗体会delete一次QMenu,然后QMenu作为临时变量又会被delete一次,就会导致crash的问题。

3、如果使用了指针QMenu,并且没有指定父窗体,例如:

QMenu *menuDemo = new QMenu;

menuDemo->addAction(“test”);

menuDemo->exec();

那么情况将会和1一样,使用某个快捷键将QMenu所在的Widget关闭掉,QMenu不会随着消失,改变了原本的流程,并且因为使用了指针,还会造成内存泄露。

综上所述,所以在使用QMenu的时候一定要使用指针的QMenu, 并且需要明确指定他的父窗体。例如在Preview这个Widget右键弹出一个QMenu,就需要用如下的方式进行创建

QMenu *menuDemo = new QMenu(Preview);

menuDemo->addAction(“test”);

menuDemo->exec();

这样子就可以保存在使用快捷键关闭Preview的时候,可以将menuDemo关闭,且销毁,不会造成内存泄露。

但是目前所说都是在关闭QMenu父窗体的时候,连带的将QMenu 销毁,不会造成内存泄露,但是如果没有销毁QMenu的父窗体,而是点击QMenu的时候造成的QMenu关闭,那么上面的写法依赖会造成内存泄露,所以此时就要使用QMenu的一个属性setAttribute(Qt::WA_DeleteOnClose), 这样就可以保证QMenu关闭的时候一定会被销毁,不会造成内存泄漏。

之所以这么修改就是为了解决目前再使用QMenu中存在的两个问题,一个是内存泄露,一个重复delete造成crash。如下的两个错误示例:

该示例中,如果在弹出QMenu的时候,如果使用快捷键(Ctrl+w)关闭文档,就会造成QMenu被析构两次,出现crash。

该示例就是会造成QMenu的内存泄露。

总结:

所以我们在使用QMenu的时候需要注意:

采用指针。

明确QMenu的父窗体

设置属性WA_DeleteOnClose

就像这样:

QMenu *menuDemo = new QMenu(Preview);

menuDemo->setAttribute(Qt::WA_DeleteOnClose);

menuDemo->addAction(“test”);

menuDemo→exec();

补充:如果QMenu中存在存在子Menu,需要将子Menu的parent设置为父Menu,否则可能会出现父Menu关闭了,但是子Menu没有关闭。

QMenu *menuDemo = new QMenu(Preview);

QMenu *subMenu = new QMenu("subMenu", menuDemo);

menuDemo->setAttribute(Qt::WA_DeleteOnClose);

menuDemo→addAction(“test”);

menuDemo->addMenu(subMenu);

menuDemo→exec();

补充:QMenu的exec中可能会存在的问题,假如现在有一个场景:存在一个Widget,做了右键操作,代码如下:

QMenu *menuDemo = new QMenu(Widget);

menuDemo->setAttribute(Qt::WA_DeleteOnClose);

menuDemo->addAction(“test”);

menuDemo→exec();

Widget.update();

但是你最后的在exec后还有使用到该Widget,但是实际上通过快捷键的方式可以再QMenu执行exec的时候将Widget销毁,这个时候就会造成Widget野指针,导致crash问题,对于该问题目前有两种想法,一种可以采用QMenu的popup这种异步的方式,然后将Widget.update()放入到对应的test的action中执行,这种方式对流程上可能会有所改变,所以需要对应的模块具体问题具体进行分析。

另外一种就是可以考虑采用只能指针的方式,代码如下:

QMenu *menuDemo = new QMenu(Widget);

QPointer pointer= Widget;

menuDemo->setAttribute(Qt::WA_DeleteOnClose);

menuDemo->addAction(“test”);

menuDemo→exec();

if(!pointer)

return;

Widget.update();

就是采用智能指针来判断该Widget是否已经被释放,如果已经被释放则不再往下执行。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值