添加qmenubar后不会调用析构函数

时间:2011-09-10 11:46:56

标签: python qt qt4 pyqt pyqt4

我有以下文件(主窗口/ UI): files

UI:

# -*- 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_())

来自以下行:

的菜单项...

... self.connect

没有注释

,永远不会调用来自UI的析构函数。如果他们被评论一切正常。有什么想法吗?

1 个答案:

答案 0 :(得分:2)

您不能依赖__del__为所有对象调用,尤其是当您的程序结束时(请参阅that other answer

根据PyQt documentation

  

但是,如果一个槽是lambda函数或部分函数那么   它的引用计数自动递增以防止它   立即被垃圾收集。

当你连接lambda函数的信号时,可能会创建对Browser对象的一些循环引用,这就是防止它被销毁的原因。由ui引用Browser,它也不会被销毁。

因此,当这些插槽是lambda函数时,您必须手动断开插槽。或使用除lambda之外的其他方法将额外参数绑定到插槽(例如QSignalMapper,或将QAction作为参数的QMenu.triggered信号):

def __init__(self, parent):
    ...
    for item in menuitems:
        entry = menu.addAction(item)
    menu.triggered.connect(self.doStuff)

def doStuff(self, entry):
    print entry.text()