动态创建的选项卡-选项卡关闭时销毁对象
Dynamically created tabs - destroy object when tab closed
我正在动态创建多个选项卡,我想知道当我关闭选项卡时,是否真的销毁了对象?
我已经将动态创建标签的属性设置为QtCore.Qt.WA_DeleteOnClose
我假设设置该属性不会执行任何操作,因为不会对其调用 closeEvent。
self.tabWidget.tabCloseRequested.connect(self.close_handler) # connect close button to slot
def close_handler(self, index):
'Remove added tab if applicable'
try:
#self.tabWidget.widget(index).deleteLater() #does this need to be added?
self.tabWidget.removeTab(index)
except:
Data.logger.exception('Exception occured:')
如何确保对象被销毁?
试一试:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Window(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
self.qtabwidget = QtWidgets.QTabWidget(self)
widget = QtWidgets.QPlainTextEdit("QPlainTextEdit 1")
label = 'Tab &1'
tab_index1 = self.qtabwidget.addTab(widget, label)
widget2 = QtWidgets.QPlainTextEdit("QPlainTextEdit 2")
tab_index2 = self.qtabwidget.addTab(widget2, 'Tab &2')
self.qtabwidget.setTabIcon(tab_index2, QtGui.QIcon('im.png'))
self.qtabwidget.setIconSize(QtCore.QSize(32, 32))
self.qtabwidget.addTab(
QtWidgets.QLabel("QLabel Tab &3", alignment=QtCore.Qt.AlignCenter),
QtGui.QIcon('Ok.png'),
'Tab &3')
self.qtabwidget.setTabShape(QtWidgets.QTabWidget.Triangular)
self.qtabwidget.setTabPosition(QtWidgets.QTabWidget.East)
self.qtabwidget.setTabsClosable(True)
self.qtabwidget.tabCloseRequested.connect(self.close_handler)
self.qtabwidget.currentChanged.connect(self.qtabwidget_currentchanged)
self.setCentralWidget(self.qtabwidget)
@QtCore.pyqtSlot(int)
def close_handler(self, index):
"""
Removes a tab with the specified index, but first deletes the widget it contains.
"""
# gets the widget
widget = self.qtabwidget.widget(index)
# if the widget exists
if widget:
# removes the widget
widget.deleteLater()
# removes the tab of the QTabWidget
self.qtabwidget.removeTab(index)
@QtCore.pyqtSlot(int)
def qtabwidget_currentchanged(self, index):
print(f"The new index of the current page: {index}")
if __name__ == '__main__':
application = QtWidgets.QApplication(sys.argv)
window = Window()
window.setWindowTitle('QTabWidget')
window.resize(400, 400)
window.show()
sys.exit(application.exec_())
我的答案是为了解释其他答案没有说明的细节,以便你了解Qt是如何处理内存的。
如果你想知道一个QObject是否被消除那么你必须使用destroyed
信号。
如果你想删除一个QObject,你必须使用deleteLater()方法。
在删除添加到 QTabWidget 的小部件的情况下,这将通知 QTabBar 它将被删除,因此访问 non-reserved 内存没有问题。
综合以上,可能的解决方案是:
def close_handler(self, index):
widget = self.tabWidget.widget(index)
widget.deleteLater()
您可以通过以下示例进行检查:
from PyQt5 import QtCore, QtGui, QtWidgets, QtWebEngineWidgets
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.tabWidget = QtWidgets.QTabWidget(tabsClosable=True)
self.tabWidget.tabCloseRequested.connect(self.onTabCloseRequested)
self.setCentralWidget(self.tabWidget)
for i in range(10):
widget = QtWidgets.QWidget()
widget.destroyed.connect(
lambda obj: print(
"deleted {}, count: {}".format(obj, self.tabWidget.count())
)
)
self.tabWidget.addTab(widget, "Tab %s" % (i))
@QtCore.pyqtSlot(int)
def onTabCloseRequested(self, index):
widget = self.tabWidget.widget(index)
widget.deleteLater()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.resize(640, 480)
w.show()
sys.exit(app.exec_())
如您所见,没有必要使用属性Qt::WA_DeleteOnClose,但如果您使用它,关闭小部件就足够了。
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.tabWidget = QtWidgets.QTabWidget(tabsClosable=True)
self.tabWidget.tabCloseRequested.connect(self.onTabCloseRequested)
self.setCentralWidget(self.tabWidget)
for i in range(10):
widget = QtWidgets.QWidget()
widget.setAttribute(QtCore.Qt.WA_DeleteOnClose)
widget.destroyed.connect(
lambda obj: print(
"deleted {}, count: {}".format(obj, self.tabWidget.count())
)
)
self.tabWidget.addTab(widget, "Tab %s" % (i))
@QtCore.pyqtSlot(int)
def onTabCloseRequested(self, index):
widget = self.tabWidget.widget(index)
widget.close()
没有必要使用removeTab()
,因为这不会破坏小部件,该方法被认为是当您想将小部件删除到另一个小部件时。
我正在动态创建多个选项卡,我想知道当我关闭选项卡时,是否真的销毁了对象?
我已经将动态创建标签的属性设置为QtCore.Qt.WA_DeleteOnClose
我假设设置该属性不会执行任何操作,因为不会对其调用 closeEvent。
self.tabWidget.tabCloseRequested.connect(self.close_handler) # connect close button to slot
def close_handler(self, index):
'Remove added tab if applicable'
try:
#self.tabWidget.widget(index).deleteLater() #does this need to be added?
self.tabWidget.removeTab(index)
except:
Data.logger.exception('Exception occured:')
如何确保对象被销毁?
试一试:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Window(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
self.qtabwidget = QtWidgets.QTabWidget(self)
widget = QtWidgets.QPlainTextEdit("QPlainTextEdit 1")
label = 'Tab &1'
tab_index1 = self.qtabwidget.addTab(widget, label)
widget2 = QtWidgets.QPlainTextEdit("QPlainTextEdit 2")
tab_index2 = self.qtabwidget.addTab(widget2, 'Tab &2')
self.qtabwidget.setTabIcon(tab_index2, QtGui.QIcon('im.png'))
self.qtabwidget.setIconSize(QtCore.QSize(32, 32))
self.qtabwidget.addTab(
QtWidgets.QLabel("QLabel Tab &3", alignment=QtCore.Qt.AlignCenter),
QtGui.QIcon('Ok.png'),
'Tab &3')
self.qtabwidget.setTabShape(QtWidgets.QTabWidget.Triangular)
self.qtabwidget.setTabPosition(QtWidgets.QTabWidget.East)
self.qtabwidget.setTabsClosable(True)
self.qtabwidget.tabCloseRequested.connect(self.close_handler)
self.qtabwidget.currentChanged.connect(self.qtabwidget_currentchanged)
self.setCentralWidget(self.qtabwidget)
@QtCore.pyqtSlot(int)
def close_handler(self, index):
"""
Removes a tab with the specified index, but first deletes the widget it contains.
"""
# gets the widget
widget = self.qtabwidget.widget(index)
# if the widget exists
if widget:
# removes the widget
widget.deleteLater()
# removes the tab of the QTabWidget
self.qtabwidget.removeTab(index)
@QtCore.pyqtSlot(int)
def qtabwidget_currentchanged(self, index):
print(f"The new index of the current page: {index}")
if __name__ == '__main__':
application = QtWidgets.QApplication(sys.argv)
window = Window()
window.setWindowTitle('QTabWidget')
window.resize(400, 400)
window.show()
sys.exit(application.exec_())
我的答案是为了解释其他答案没有说明的细节,以便你了解Qt是如何处理内存的。
如果你想知道一个QObject是否被消除那么你必须使用destroyed
信号。
如果你想删除一个QObject,你必须使用deleteLater()方法。
在删除添加到 QTabWidget 的小部件的情况下,这将通知 QTabBar 它将被删除,因此访问 non-reserved 内存没有问题。
综合以上,可能的解决方案是:
def close_handler(self, index):
widget = self.tabWidget.widget(index)
widget.deleteLater()
您可以通过以下示例进行检查:
from PyQt5 import QtCore, QtGui, QtWidgets, QtWebEngineWidgets
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.tabWidget = QtWidgets.QTabWidget(tabsClosable=True)
self.tabWidget.tabCloseRequested.connect(self.onTabCloseRequested)
self.setCentralWidget(self.tabWidget)
for i in range(10):
widget = QtWidgets.QWidget()
widget.destroyed.connect(
lambda obj: print(
"deleted {}, count: {}".format(obj, self.tabWidget.count())
)
)
self.tabWidget.addTab(widget, "Tab %s" % (i))
@QtCore.pyqtSlot(int)
def onTabCloseRequested(self, index):
widget = self.tabWidget.widget(index)
widget.deleteLater()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.resize(640, 480)
w.show()
sys.exit(app.exec_())
如您所见,没有必要使用属性Qt::WA_DeleteOnClose,但如果您使用它,关闭小部件就足够了。
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.tabWidget = QtWidgets.QTabWidget(tabsClosable=True)
self.tabWidget.tabCloseRequested.connect(self.onTabCloseRequested)
self.setCentralWidget(self.tabWidget)
for i in range(10):
widget = QtWidgets.QWidget()
widget.setAttribute(QtCore.Qt.WA_DeleteOnClose)
widget.destroyed.connect(
lambda obj: print(
"deleted {}, count: {}".format(obj, self.tabWidget.count())
)
)
self.tabWidget.addTab(widget, "Tab %s" % (i))
@QtCore.pyqtSlot(int)
def onTabCloseRequested(self, index):
widget = self.tabWidget.widget(index)
widget.close()
没有必要使用removeTab()
,因为这不会破坏小部件,该方法被认为是当您想将小部件删除到另一个小部件时。