添加qmenubar后析构函数未被调用
我有以下文件(主窗口/用户界面):
用户界面:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'mainwindow.ui'
#
# Created: Sat Apr 23 15:53:12 2011
# by: PyQt4 UI code generator 4.7.3
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
class Ui_MainWindow(object):
### Presetting Model ###
model = QtGui.QFileSystemModel()
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1000, 600)
self.centralWidget = QtGui.QWidget(MainWindow)
self.centralWidget.setObjectName("centralWidget")
self.horizontalLayout_2 = QtGui.QHBoxLayout(self.centralWidget)
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.horizontalLayout = QtGui.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.treeView = QtGui.QTreeView(self.centralWidget)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(2)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.treeView.sizePolicy().hasHeightForWidth())
self.treeView.setSizePolicy(sizePolicy)
self.treeView.setHeaderHidden(True)
self.treeView.setObjectName("treeView")
self.horizontalLayout.addWidget(self.treeView)
self.plainTextEdit = QtGui.QPlainTextEdit(self.centralWidget)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(4)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.plainTextEdit.sizePolicy().hasHeightForWidth())
self.plainTextEdit.setSizePolicy(sizePolicy)
self.plainTextEdit.setObjectName("plainTextEdit")
self.horizontalLayout.addWidget(self.plainTextEdit)
self.horizontalLayout_2.addLayout(self.horizontalLayout)
MainWindow.setCentralWidget(self.centralWidget)
### MENU ###
self.menuBar = QtGui.QMenuBar(MainWindow)
self.menuBar.setGeometry(QtCore.QRect(0, 0, 600, 27))
self.menuBar.setObjectName("menuBar")
MainWindow.setMenuBar(self.menuBar)
### Setting up tree view model ###
self.treeView.setModel(self.model)
self.treeView.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
# self.treeView.setRootIndex(self.model.setRootPath(Xmldocument.directorypath))
### Hiding additional info in treeview ###
hHeader = self.treeView.header()
hHeader.hideSection(1)
hHeader.hideSection(2)
hHeader.hideSection(3)
MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "VeloCondDB Browser", None, QtGui.QApplication.UnicodeUTF8))
QtCore.QMetaObject.connectSlotsByName(MainWindow)
##############################################################
def __del__(self):
print "DESTRUCTOR"
主窗口:
import sys
import os
from browserclass_UI import Ui_MainWindow
from PyQt4 import QtCore, QtGui
class Browser(QtGui.QMainWindow):
#############################################################################################
def __init__(self, parent=None):
"""Constructor for the main window."""
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
menuitems = ["Open", "Close"]
menu = self.ui.menuBar.addMenu('File')
for item in menuitems:
entry = menu.addAction(item)
self.connect(entry, QtCore.SIGNAL('triggered()'), lambda item=item: self.doStuff(item))
#############################################################################################
def doStuff(self, item):
print item
#############################################################################################
if __name__ == "__main__":
browser = QtGui.QApplication(sys.argv)
myapp = Browser()
myapp.show()
sys.exit(browser.exec_())
当以下代码行:
menuitems...
到
self.connect...
没有被注释掉时,用户界面的析构函数就不会被调用。如果把它们注释掉,一切就正常了。有什么想法吗?
1 个回答
2
你不能指望所有对象的 __del__
方法都会被调用,特别是在你的程序结束的时候(可以参考这个答案)
根据PyQt的文档:
不过,如果一个槽是一个lambda函数或者部分函数,那么它的引用计数会自动增加,以防止它被立即垃圾回收。
当你把信号连接到lambda函数时,可能会创建一些对你的 Browser
对象的循环引用,这就是它无法被销毁的原因。因为 ui
被 Browser
引用,所以它也不会被销毁。
所以,当这些槽是lambda函数时,你必须手动断开连接。或者使用其他方法来绑定额外的参数到槽(例如,使用 QSignalMapper,或者信号 QMenu.triggered,它的参数是 QAction):
def __init__(self, parent):
...
for item in menuitems:
entry = menu.addAction(item)
menu.triggered.connect(self.doStuff)
def doStuff(self, entry):
print entry.text()