首页 > 编程语言 >Qt窗口关闭和应用程序停止是否调用析构函数的一些说明

Qt窗口关闭和应用程序停止是否调用析构函数的一些说明

时间:2023-05-25 15:37:24浏览次数:48  
标签:析构 窗口 Qt 应用程序 调用 关闭 函数


这几天一直在模仿QQ做一个即时通讯软件,过程不是很顺利,表现在窗口关闭,应用程序依旧存在,应用程序异常结束,关闭子窗口,主窗口跟着关闭,所以总结了一些内容,方便日后获取。

Qt窗口关闭和应用程序停止是否调用析构函数的一些说明_Qt窗口


Qt窗口关闭和应用程序停止是否调用析构函数的一些说明_关闭窗口_02

如果对这个项目有兴趣的话可以前往GitHub:https://github.com/FdogMain/FdogInstantMessaging


main函数中,在栈上创建的窗口,关闭的时候自动调用析构函数,这种情况不可以使用this->setAttribute(Qt::WA_DeleteOnClose);,关闭时会出现异常,如果是在堆上创建,则可以使用this->setAttribute(Qt::WA_DeleteOnClose),调用析构函数时,不会有异常。

当关闭窗口时会调用close函数,这个函数发送一个关闭事件 QCloseEvent,接着窗口将会被隐藏,如果想实现关闭时进行询问,可以拦截QCloseEvent事件,也就是重写QCloseEvent,可以让用户来选择关闭,还是取消。

在不加Qt::WA_DeleteOnClose时,选择关闭,窗口将会消失,其实调用了hide,如果加了之后,除了调用hide,还会调用deleteLater方法来将窗口释放掉,在不加这个属性的情况下,close和hide,还有servisibel的功能是一样,只是会隐藏窗口对象而已,不会销毁对象。


在main,栈上面创建一个窗口A,关闭窗口A时,会调用析构函数。
如果在这个窗口A的构造函数中再创建一个窗口B,并且在A的析构函数中对B进行释放。

第一种形式:

MainWindow * b = new MainWindow();

当关闭窗口A,再关闭窗口B时,创建B的析构函数被调用,窗口A的析构函数被调用 (这种关闭方式有明显的卡顿,当关闭A,按照规则,B应该被关掉,释放,但是B窗口还显示在桌面,多次运行,发现还会存在A析构不执行的问题(析构中的打印语句并未被打印在控制台),所以这种方式存在问题)

反过来,当先关闭窗口B,再关闭窗口A,B的析构函数被调用,窗口A的析构函数被调用 (这种关闭方式无卡顿,实际上是B窗口被隐藏,并未主动执行析构,而在A的析构函数中被动执行,这也是为什么关闭B时,显示并未调用B析构,而关闭A时,才显示调用B析构的原因)

我们给窗口B添加Qt::WA_DeleteOnClose试一下(构造函数中添加setAttribute(Qt::WA_DeleteOnClose)),因为窗口B是窗口在堆上的,可以使用setAttribute(Qt::WA_DeleteOnClose)),

还是先关闭窗口A,再关闭窗口B,显示调用了窗口B的析构函数,然后出现异常,这个异常应该是重复析构B发送的异常。

把窗口A中关于窗口B释放的代码去掉,显示调用了窗口B的析构函数,调用窗口A的析构函数,但是没有出现异常(存在卡顿,多次运行,发现还会存在A析构不执行的问题(析构中的打印语句并未被打印在控制台))。

现在反过来,先关闭窗口B,由于窗口B设置了setAttribute(Qt::WA_DeleteOnClose))属性,立即执行了析构函数,接着关闭窗口A,如果不出意外的话,应该会出现异常,因为窗口B已经被释放,再在窗口A中再次释放B会报异常,把A中析构函数中的释放B的代码再次注释,运行,显示依次调用了窗口B的析构函数,窗口A的析构函数(无卡顿)。


第二种形式,指定父窗口

MainWindow * b = new MainWindow(this);

A窗口析构没有写释放B窗口的代码情况下:

关闭A窗口(被释放),B窗口跟着关闭(被释放)(无卡顿)。

关闭B窗口(只是隐藏),关闭A窗口(被释放)(无卡顿)。

再次试着给 b 添加setAttribute(Qt::WA_DeleteOnClose))属性,关闭B窗口,执行B析构,再关闭A,执行A的析构(无卡顿)。

关闭A窗口,执行A的析构,执行B的析构,并且B窗口被关闭(无卡顿)。

这里是因为QT的父子对象机制在起作用,原因就在于那个this。

当我们使用父对象来创建一个对象的时候 ,父对象会把这个对象添加到自己的子对象列表中。当这个父对象被删除的时候,它会遍历它的子对象类表并且删除每一个子对象,然后子对象们自己再删除它们自己的子对象,这样递归调用直到所有对象都被删除,所以如果new出来的控件,如果有指定父对象,无需我们手动删除。

还有一个发现,就是其他控件如果指定A窗口作为父窗口,是会被嵌入在A窗口中的,但是MainWindow这个类的窗口不会被嵌入
反过来则不然。

但是上面这些仅仅是在基本情况下,当我把窗口属性设置为无边框,无任务栏之后等等不同属性之后,再次关闭窗口,析构函数不会被自动调用,换句话说就是只是窗口关闭了,但是应用程序本身还没有关闭,最明显的特征就是当你关闭了窗口,qt的应用程序输出窗口还是显示着红色的方块而不是绿色的三角。

这个时候可以在你想要关闭的地方添加下列代码,应用程序就会被关闭。

QApplication* app;
    app->quit();

还有一种情况就是在MainWindow中创建widget窗口,但是一关闭最后一个widget,MainWindow就会被关闭,是不是不可思议,在没找到解决方案之前,我只能判断是不是最后一个widget,如果是我就隐藏,而不是关闭,举个例子。

例如qq 主界面是MainWindow 双击好友生成widget窗口。

当关闭这些widget窗口到最后一个的时候,主窗口会跟着关闭,出现这种症状的原因之一,是设置了窗口的属性

也就是使用了这个函数setWindowFlags(),一不做二不休,将这个widget窗口再添加一个属性setWindowFlag(Qt::CoverWindow);

这个问题可能会不存在了~

还有一个问题就是关闭窗口,可能会报程序异常结束,这个错误也和main中窗口创建的位置有关。



标签:析构,窗口,Qt,应用程序,调用,关闭,函数
From: https://blog.51cto.com/u_14770531/6348219

相关文章

  • Fdog系列(六):利用Qt通过服务端进行客户端与客户端通信(资料少,建议收藏)
    文章目录一.前言二.正文1.客户端与客户端通信思路2.代码实现(1)服务端的实现(2)客户端的实现一.前言Fdog已写文章目录:Fdog系列(一):思来想去,不如写一个聊天软件,那就从仿QQ注册页面开始吧。Fdog系列(二):html写完注册页面之后怎么办,用java写后台响应呀。Fdog系列(三):使用腾讯云短信接口发......
  • 基于Qt的网络音乐播放器(五)实现歌词滚动显示
    文章目录1.思路和效果图2.歌词的解析与存储3.onDurationChanged()4.总结网络播放器系列:qt布局和样式表基于Qt的网络音乐播放器(一)添加音频文件,播放音乐,更新进度条基于Qt的网络音乐播放器(二)切换歌曲,调节音量,调节语速,暂停基于Qt的网络音乐播放器(三)通过酷狗音乐的api接口,返回json格......
  • Qt读取qss文件失败或qss不生效解决方案
            最近在写qt加载样式表的博文,发现qss文件要么打开失败,要么加载成功,但是不生效,经过一番搜索也是算解决了这个问题。读取qss失败:读取文件的方式有两种,一种是绝对路径,一种是相对路径://绝对路径C:\\Users\\fdog\\Desktop\\sheet.qss//相对路径./lib/sheet.qss出现错......
  • Qt父窗口与子窗口数据交互(用拾色器举例)
    文章目录一.效果图二.实现1.在子窗口中声明信号2.在主窗口中声明并实现槽函数,并进行信号与槽的绑定3.在子窗口中发送信号(emit),并完成其控件的相应4.在子窗口的构造函数中传入需要的主窗口数据一.效果图二.实现首先我们创建主窗口和子窗口,并拖动控件,完成基本界面。这里的布局以及......
  • Qt正则表达式类QRegExp(附检验小程序)
           在许多场景中,我们需要验证用户输入的数据是否有效,或者是查找并修改文本,或者是提取指定数据,为此,相对于Qstring的一些函数,QT提供了一个更加强大的类——QRegExp,使用函数配合正则表达式来操作字符串,QRegExp可以进行下面的操作,并附带检验小程序,可在文末下载。一.正则表达......
  • 基于Qt的音乐播放器(三)通过酷狗音乐的api接口,返回json格式歌曲信息(播放地址,歌词,图片)
    2020博客之星年度总评选进行中:请为74号的狗子投上宝贵的一票!我的投票地址:点击为我投票文章目录前言1.获取歌曲搜索列表api接口2.获取单个歌曲详细信息包括歌词3.总结前言首先说明,本教程仅供个人学习,研究使用,禁止用于任何的商业和非法用途。(手动狗头)之所以要研究这个,是因为我想......
  • Gartner 魔力象限:应用程序安全测试 2023 - Magic Quadrant for Application Security
    MagicQuadrantforApplicationSecurityTesting2023Gartner魔力象限:应用程序安全测试2023请访问原文链接:https://sysin.org/blog/gartner-magic-quadrant-ast-2023/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.orgGartner魔力象限:应用程序安全测试2023Magic......
  • 【盘点】界面控件DevExpress WPF的几大应用程序主题
    DevExpressWPF控件包含了50+个应用程序主题和40个调色板,用户可以在发布应用程序是指定主题,或允许最终用户动态修改WPF应用程序的外观和样式,其中主题带有调色板,可以进一步个性化您的UI!PS:DevExpressWPF拥有120+个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。......
  • 【转载】vs设置qt应用程序logo
    1、下载一个ico,拷贝到主函数工程目录下 2、新建一个文件如logo.rc,内容如下:IDI_ICON1ICONDISCARDABLE“logo.ico”3、修改主函数工程文件Main.vcxproj在文件最后添加<ItemGroup><ResourceCompileInclude="logo.rc"/></ItemGroup> 4、生成工程后即可看到ex......
  • MQTT入门DEMO(Java语言)
    目录快速开始准备下载及安装第一次安装EMQX第一次运行EMQX客户端代码快速开始准备MQTT简介EMQX简介下载及安装第一次安装EMQX版本选择EMQX支持多种操作系统,请选择合适您的版本下载。下载地址:https://www.emqx.io/cn/downloads#broker在MicrosoftWindows下安装目前EMQX......