Деструктор не вызывается после добавления qmenubar - PullRequest
2 голосов
/ 10 сентября 2011

У меня есть следующие файлы (главное окно / интерфейс): файлы

интерфейс:

# -*- 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 ...

не комментируются, деструктор из пользовательского интерфейса никогда не используетсяназывается.Если они прокомментированы, все работает отлично.Есть идеи?

1 Ответ

2 голосов
/ 10 сентября 2011

Вы не можете полагаться на то, что __del__ вызывается для всех ваших объектов, особенно когда ваша программа заканчивается (см. этот другой ответ )

Согласно документации PyQt :

Однако, если слот является лямбда-функцией или частичной функцией, то его счетчик ссылок автоматически увеличивается, чтобы предотвратить быть немедленно собранным мусором.

Некоторые циклические ссылки на ваш Browser объект могут быть созданы при подключении сигнала, который выполняет лямбда-функция, и именно это удерживает его от разрушения. Поскольку на ui ссылается Browser, он также не уничтожается.

Итак, вы должны отключить слоты вручную, когда эти слоты являются лямбда-функциями. или используйте другой метод, кроме лямбды, для привязки дополнительных параметров к слоту (например, 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()
...