【OpenGL开发】PyQt在关闭应用程序时没有运行析构函数的问题

news2024/11/16 15:41:47

PyQt在关闭应用程序时没有运行析构函数的问题

在这里插入图片描述

目录

  • 一、说明
  • 二、python的析构函数
  • 三、QT5 存在一些问题
  • 四、PyQt5 存在一些问题
  • 五、OpenGL的析构问题

一、说明

   应用QT做程序界面,在程序退出的时候,需要调用析构函数释放资源,这个操作在Python程序中,虽然不调用析构函数,资源也可以释放。在QOpenGLWidget中,会产生一系列的buff对象,如果不能正确释放,程序将出现状况,如何解决?

   但是,出现讨厌的错误提示,比如下图:
在这里插入图片描述

二、python的析构函数

   在PyQt中,当一个类的实例被销毁时,Python会自动调用它的析构函数(即__del__方法)。析构函数主要用于释放资源(例如关闭文件、断开网络连接等),以确保在对象被销毁之前进行必要的清理工作。

from PyQt5.QtWidgets import QApplication, QMainWindow

class MyWindow(QMainWindow):
    def __init__(self):
        super().__init__()

    def __del__(self):
        print("析构函数被调用")

app = QApplication([])
window = MyWindow()
window.show()
app.exec_()

   在PyQt中,当一个类的实例被销毁时,Python会自动调用它的析构函数(即__del__方法)。析构函数主要用于释放资源(例如关闭文件、断开网络连接等),以确保在对象被销毁之前进行必要的清理工作。

三、QT5 存在一些问题

   按照文库的说法,“如果子窗体初始化了父窗体的parent,只有父窗体析构时才执行自己的析构函数。”

   根据我的经验,系统默认的构造函数中parent都有默认值0,而构造函数的实现中,都有初始化列表指定父类的parent为当前parent,如果不指定,也就是0。这里还不能把parent指定位父窗体,否则子窗体会作为一个父窗体当中的“部件”而存在。父类和父窗体不是一个东西。所以文库当中的说法我暂时不太明白。

   我的想法是这样,既是不初始化父类的parent,它的构造函数中parent参数依然会有默认值为空指针,所以是否执行析构函数,和初始化父类构造函数我想不出联系。

   但是文库中给出了解决方法,在子窗体构造函数中加一句即可:

setAttribute(Qt::WA_DeleteOnClose);

   这才是最重要的。根据qt的文档,这个属性就是在close时delete。

Qt::WA_DeleteOnClose 55
 
Makes Qt delete this widget when the widget has accepted the close event (see QWidget::closeEvent()).

   之所以说是坑,就是每次设计窗体时,总觉得想当然可以关闭时执行析构,但事实上必须加这一句,总会忘掉,特此记录,提醒自己。

四、PyQt5 存在一些问题

   有时在关闭应用程序时,PyQt不会自动调用类的析构函数,可能导致一些资源无法正常释放。这可能是因为应用程序的主事件循环在关闭窗口时仍在运行,从而导致类的实例无法被销毁。
   为了解决这个问题,我们可以通过重写QMainWindow的closeEvent方法来手动触发析构函数的调用。

from PyQt5.QtWidgets import QApplication, QMainWindow

class MyWindow(QMainWindow):
    def __init__(self):
        super().__init__()

    def __del__(self):
        print("析构函数被调用")

    def closeEvent(self, event):
        self.__del__()  # 手动调用析构函数
        event.accept()

app = QApplication([])
window = MyWindow()
window.show()
app.exec_()

   在上面的示例代码中,我们重写了closeEvent方法,并在其中手动调用了析构函数。通过这种方式,我们可以确保在关闭窗口时,析构函数会被正确地调用。

   在PyQt中,当一个类的实例被销毁时,Python会自动调用它的析构函数(即__del__方法)。析构函数主要用于释放资源(例如关闭文件、断开网络连接等),以确保在对象被销毁之前进行必要的清理工作。

五、OpenGL的析构问题

OpenGL对自身的上下文是非常敏感的,稍有不慎可能就会导致内存泄漏,或者没有释放正确,就比如 QOpenGLVertexArrayObject::destroy() failed to restore current context 问题,由于上下文的问题没有办法正确的释放QOpenGLVertexArrayObject VAO对象。

发生的原因:我想在QOpenGLWidget的析构函数 delete 掉我的网格类对象,网格类对象内使用了VAO对象也就是QOpenGLVertexArrayObject 这个类,两个类的析构大致如下

Mesh类:

Mesh::~Mesh(){
  	m_VBO.destroy();
	m_VAO.destroy();
}
MyOpenGLWidget类:

MyOpenGLWidget::~MyOpenGLWidget(){
    delete mesh;
}

在关闭窗口后控制台面板就输出了这个问题

在这里插入图片描述

解决方法:

这个问题的原因就是因为在OpenGL窗口结束了之后,最后在析构的时候还有使用到OpenGL的东西,就是delete mesh对象时mesh的析构又调用了QtOpenGL相关内容导致的OpenGL上下文不正确。

所以在MyOpenGLWidget的析构函数中加入下面的函数来确保上下文正确。

MyOpenGLWidget::~MyOpenGLWidget(){
    // 确保释放opengl资源时上下文正确
    makeCurrent();
    delete mesh;
    doneCurrent();
 
}

这也是一个解决办法,如果还有其他办法再说吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1595292.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

跟TED演讲学英文:Why AI is incredibly smart and shockingly stupid by Yejin Choi

Why AI is incredibly smart and shockingly stupid Link: https://www.ted.com/talks/yejin_choi_why_ai_is_incredibly_smart_and_shockingly_stupid Speaker: Yejin Choi Date: April 2023 文章目录 Why AI is incredibly smart and shockingly stupidIntroductionVocabul…

通过调用Vcenter-Api获取Vcenter中服务器信息

通过调用Vcenter-Api获取Vcenter中服务器信息 文章目录 通过调用Vcenter-Api获取Vcenter中服务器信息1. 获取Vmware API帮助文档2. 获取访问凭证3. 获取服务器清单4. 获取服务器更多信息5. 获取虚机更多信息6. 获取磁盘信息7. 获取操作系统相关 1. 获取Vmware API帮助文档 htt…

面试八股——Spring——AOP与事务

AOP的定义 事务的实现 事务的失效场景 异常捕获处理 下图中由于②导致异常: 原因: 解决办法:自己抛出一个非检查异常(具体原因看“抛出检查异常”)。 抛出检查异常 由于①出错,导致抛出了检查异常 原因&…

[linux api] of_irq_init

总结: 以如下级联的中断控制器为例: of_irq_init会确保先初始化父控制器再初始化子控制器,也即整体按照层序遍历的顺序进行初始化,以上图为例,其初始化顺序为: intc0intc1-2intc3-6具体实现则分为两个阶段: 第一阶段 遍历所有设备节点,并与参数matches进行匹配,找…

Servlet实现常用功能及其他方法

getParameter 获取body或url中指定的key/value值 String classIdreq.getParameter("classId"); getQueryString 获取请求的所有查询参数key,values1 String queryStringreq.getQueryString(); from表单提交 前端通过from表单提交用户名和密码 <!DOCTYPE htm…

# 达梦sql查询 Sql 优化

达梦sql查询 Sql 优化 文章目录 达梦sql查询 Sql 优化注意点测试数据单表查询 Sort 语句优化优化过程 多表关联SORT 优化函数索引的使用 注意点 关于优化过程中工具的选用&#xff0c;推荐使用自带的DM Manage&#xff0c;其它工具在查看执行计划等时候不明确在执行计划中命中…

计算机网络常问面试题

一.HTTPS是如何保证安全传输的 https通过使⽤对称加密、⾮对称加密、数字证书等⽅式来保证数据的安全传输。 客户端向服务端发送数据之前&#xff0c;需要先建⽴TCP连接&#xff0c;所以需要先建⽴TCP连接&#xff0c;建⽴完TCP连接后&#xff0c;服务端会先给客户端发送公钥…

网络网络层之(2)ARP协议

网络网络层之(2)ARP协议 Author&#xff1a;Once Day Date: 2024年4月1日 漫漫长路&#xff0c;有人对你笑过嘛… 全系列文档可参考专栏&#xff1a;通信网络技术_Once-Day的博客-CSDN博客。 参考文档: 《TCP/IP详解卷一》arp(8) - Linux manual page (man7.org)彻底搞懂系…

配置香橙派摄像头服务每次开机自动启动

目录 1.创建一个mjpg.sh脚本 2.在脚本中添加以下内容 3.增加可执行权限 4.在/etc/xdg/autostart/下创建mjpg.desktop 文件输入以下内容 1.创建一个mjpg.sh脚本 touch mjpg.sh 2.在脚本中添加以下内容 #!/bin/bash cd /home/orangepi/Myorangepi/zhinenglajitong/mjpg-stre…

分布式幂等性

1. 什么是幂等性&#xff1f; 幂等性是指在分布式系统中&#xff0c;一个操作多次执行的结果与其执行一次的结果相同。设计具有幂等性的分布式系统可以有效避免数据不一致和重复处理的问题。 幂等系统的应用场景 在微服务架构下&#xff0c;由于分布式天然特性的时序问题, 以…

解决动态规划问题

文章目录 动态规划的定义动态规划的核心思想青蛙跳阶问题解法一&#xff1a;暴力递归解法二&#xff1a;带备忘录的递归解法&#xff08;自顶向下&#xff09;解法三&#xff1a;动态规划&#xff08;自底向上&#xff09; 动态规划的解题套路什么样的问题考虑使用动态规划&…

英语新概念2-回译法-lesson6

我刚刚搬家去柏林大街的房子里。昨天一个流浪汉敲我的门,他想我寻求一顿饭和一杯啤酒。未拒绝了这个请求之后,这个流浪汉倒立着唱歌,我给他了一顿饭,他吃了食物并且喝了啤酒,然后他把一片奶酪放到他的口袋里然后走开了。过了一会儿,一个领居告诉我关于这个流浪汉的事情。…

GAN:对抗生成网络【通俗易懂】

一、概述 对抗生成网络&#xff08;GAN&#xff09;是一种深度学习模型&#xff0c;由两个神经网络组成&#xff1a;生成器G和判别器D。这两个网络被训练来协同工作&#xff0c;以生成接近真实数据的新样本。 生成器的任务是接收一个随机噪声向量&#xff0c;并将其转换为与真…

java数据结构与算法刷题-----LeetCode371. 两整数之和

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 文章目录 位运算 位运算 解题思路&#xff1a;时间复杂度O( l o g 2 m a …

网络篇09 | 运输层 udp

网络篇09 | 运输层 udp 01 简介UDP 是面向报文的 02 报文协议 01 简介 UDP 只在 IP 的数据报服务之上增加了一些功能&#xff1a;复用和分用、差错检测 UDP 的主要特点&#xff1a;无连接。发送数据之前不需要建立连接。 使用尽最大努力交付。即不保证可靠交付。 面向报文。…

C# dynamic 数据类型

在C#中&#xff0c;dynamic是一种数据类型&#xff0c;它允许在运行时推迟类型检查和绑定。使用dynamic类型&#xff0c;可以编写更具灵活性的代码&#xff0c;因为它允许在编译时不指定变量的类型&#xff0c;而是在运行时根据实际情况进行解析。 dynamic类型的变量可以存储任…

Oracle 19c RAC 补丁升级 补丁回退

补丁升级流程 补丁升级 停止集群备份家目录 两节点分别操作 cd /u01/app/19.3.0/grid/bin/ crsctl stop crs tar -zcvf /u01/app.tar.gz /u01/app /u01/app/19.0.0/grid/bin/crsctl start crs 两节点OPatch替换 --- 表示 root 用户&#xff0c;$ 表示 Oracle 用户提示符&#…

list 简化版模拟实现

1ListNode template<class T>struct ListNode{public:ListNode(const T& x T()):_next(nullptr), _prev(nullptr), _data(x){}//private://共有可访问ListNode<T>* _next;ListNode<T>* _prev;T _data;}; 实现iterator对Node*的封装 实现运算符重载 vo…

双向链表的实现(详解)

目录 前言初始化双向链表的结构为双向链表的节点开辟空间头插尾插打印链表尾删头删查找指定位置之后的插入删除pos节点销毁双向链表 前言 链表的分类&#xff1a; 带头 不带头 单向 双向 循环 不循环 一共有 (2 * 2 * 2) 种链表 带头指的是&#xff1a;带有哨兵位节点 哨兵位&a…

基于SignalR视频聊天 一

环境 VS2022 WIN10 .NET8 VSCode VUE SignalR 1.安装SignalR客户端库 需要在Vue.js项目中安装SignalR客户端库。可以使用npm或者yarn来安装 npm install microsoft/signalr2.创建SignalR服务 创建SignalR服务&#xff0c;以便客户端&#xff08;Vue.js应用&#xff09;能…