前言:
此刻姐妹们对“python清空变量值”大致比较注重,咱们都想要学习一些“python清空变量值”的相关知识。那么小编也在网上搜集了一些关于“python清空变量值””的相关内容,希望姐妹们能喜欢,姐妹们一起来学习一下吧!问题的提出
在Qt的GUI布局中,有时候需要彻底删除一个部件,释放其占用的内存,比如在一个网格布局中,在不影响布局的情况下,需要删除其中的某个部件,我们调用removeWidget()函数将其从布局中删除,这种操作下,虽然在界面上看不到了被移除的部件,但这并不说明,部件已经被删除,所占用的内存已经被释放。实际上,这些部件并没有被删除,占用的内存并没有释放。在Python里,可以采用以下三种方法来达到目的。
方法1:使用部件的deleteLater的函数
在Qt中,所有继承自QObject的类都有一个deleteLater函数,用于在适当的时候销毁对象自身。其原理是QObject.deleteLater()并不立即将对象销毁,而是向主循环发送了-个事件(event),在主循环收到这个事件后,让所有事件都发送完一切处理好后才销毁对象,释放相应的内存。这样做的好处是可以在这些延迟删除的时间内完成一些操作,而且就算调用多次的deletelater也是安全的。坏处就是内存释放会不及时。
方法2:使用sip.delete函数删除部件
导入sip库
import PyQt5.sip
使用其delete函数来删除部件对象
sip.delete(widget)
这种方法和C++中使用delete删除对象的原理是一样的。
这种方法的好处是,立即删除对象和释放内存,坏处是,可能会导致不可预知的崩溃现象。
Qt中不建议使用手动使用delete来释放QObject对象,原因有二:
不注意父子关系可能或导致某个对象释放两次,一次是手动释放,一次是parent释放。删除一个pending events等待传递的QObject会导致崩溃,所以不能直接跨线程删除对象,而QObject析构函数会断开所有信号和槽,因此用deleteLater代替比较好,它会让所有事件都发送完一切处理好后马上清除这片内存,而且就算调用多次的deletelater也是安全的。
如果没有上述两种原因存在,可以直接使用delete来删除对象和释放内存空间。
方法3:使用del函数
python提供了del 删除变量的方式,del 删除变量的原理是,它使变量的引用计数减一,如果引用计数为0,就会被回收。这样也可以达到目的,其使用方式同方法2,效果和方法2也是一样的。
测试代码
测试代码演示使用按钮,添加一些标签,可以选择用两种不同的方式来删除添加的标签,右边打印出操作后的信息,可以看到delteLater 函数并不马上执行删除并释放空间的操作,而sip.delete则马上执行删除操作并释放组件所占用的内存空间。完整测试代码如下:
import sysfrom PyQt5 import QtCore, QtGui, QtWidgetsfrom PyQt5 import sipfrom PyQt5.QtCore import Qtfrom PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QGridLayout, QHBoxLayout, QVBoxLayout, QSplitter, QPushButton, QLabel, QPlainTextEdit) class DemoWidgetDelete(QMainWindow): def __init__(self, parent=None): super(DemoWidgetDelete, self).__init__(parent) # 设置窗口标题 self.setWindowTitle('实战PyQt5: 演示彻底删除部件') # 设置窗口大小 self.resize(480, 300) self.initUi() def initUi(self): mainLayout = QVBoxLayout() self.labelList = [] mainWidget = QWidget() mainWidget.setLayout(mainLayout) self.setCentralWidget(mainWidget) #三个按钮 btnAdd = QPushButton('添加') btnAdd.clicked.connect(self.onButtonAdd) btnRemove1 = QPushButton('移除(deleteLater)') btnRemove1.clicked.connect(self.onButtonRemove1) btnRemove2 = QPushButton('移除(sip.delete)') btnRemove2.clicked.connect(self.onButtonRemove2) hLayout = QHBoxLayout() hLayout.addWidget(btnAdd) hLayout.addWidget(btnRemove1) hLayout.addWidget(btnRemove2) self.gLayout = QGridLayout() self.gLayout.setSpacing(10) widLeft = QWidget() widLeft.setLayout(self.gLayout) self.txtShow = QPlainTextEdit() splitter = QSplitter() splitter.addWidget(widLeft) splitter.addWidget(self.txtShow) splitter.addWidget(self.txtShow) splitter.setStretchFactor(0, 1) mainLayout.addLayout(hLayout) mainLayout.addWidget(splitter) #mainLayout.addStretch(Qt.Vertical) def onButtonAdd(self): addPos = self.gLayout.count() + 1 addNum = len(self.labelList) self.labelList.append(QLabel('标签 ' + str(addPos))) self.gLayout.addWidget(self.labelList[addNum], addPos, 0) #方法1 def onButtonRemove1(self): self.txtShow.clear() self.txtShow.appendPlainText('deleteLater:') for idx in range(self.gLayout.count()+1, 1, -1): #print(self.gLayout.rowCount(), len(self.gLayout), self.gLayout.count()) self.txtShow.appendPlainText('{},{},{}'.format(self.gLayout.rowCount(), len(self.gLayout), self.gLayout.count())) wid = self.gLayout.itemAtPosition(idx-1, 0).widget() wid.deleteLater() #尝试继续访问 for idx in range (self.gLayout.count()+1, 1, -1): #print(idx, self.gLayout.itemAtPosition(idx - 1, 0).widget().size()) self.txtShow.appendPlainText('{},{}'.format(idx, self.gLayout.itemAtPosition(idx - 1, 0).widget().size())) #方法2 def onButtonRemove2(self): self.txtShow.clear() self.txtShow.appendPlainText('sip.delete:') for idx in range(self.gLayout.count()+1, 1, -1): #print(self.gLayout.rowCount(), len(self.gLayout), self.gLayout.count()) self.txtShow.appendPlainText('{},{},{}'.format(self.gLayout.rowCount(), len(self.gLayout), self.gLayout.count())) wid = self.gLayout.itemAtPosition(idx-1, 0).widget() self.gLayout.removeWidget(wid) sip.delete(wid) #尝试继续访问 for idx in range (self.gLayout.count()+1, 1, -1): #print(idx, self.gLayout.itemAtPosition(idx - 1, 0).widget().size()) self.txtShow.appendPlainText('{},{}'.format(idx, self.gLayout.itemAtPosition(idx - 1, 0).widget().size())) if __name__ == '__main__': app = QApplication(sys.argv) window = DemoWidgetDelete() window.show() sys.exit(app.exec())
运行结果如下图:
本文知识点彻底释放Qt对象的三种方法;deleteLater的优点和缺点;什么时候可以使用delete来删除部件,释放空间;使用del来删除部件。
喜欢本文内容就关注, 收藏,点赞,评论和转发。
标签: #python清空变量值