【问题标题】:Destructor isn't called after adding a qmenubar添加 qmenubar 后不调用析构函数
【发布时间】:2011-09-10 11:46:55
【问题描述】:

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

用户界面:

# -*- 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 的析构函数永远不会被调用。如果他们被评论一切正常。有什么想法吗?

【问题讨论】:

    标签: python qt qt4 pyqt pyqt4


    【解决方案1】:

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

    根据PyQt documentation

    但是,如果槽是 lambda 函数或偏函数,则 它的引用计数会自动增加以防止它 立即被垃圾回收。

    当您将信号连接到 lambda 函数时,可能会创建对您的 Browser 对象的一些循环引用,这就是防止它被破坏的原因。由于uiBrowser 引用,它也不会被破坏。

    因此,当这些插槽是 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()
    

    【讨论】:

    • 感谢您的回答和其他资源。我会调查的。
    猜你喜欢
    • 2021-07-19
    • 2017-03-02
    • 2013-01-01
    • 2015-03-29
    • 2010-11-10
    • 1970-01-01
    • 2014-09-18
    • 2015-02-21
    • 2011-07-19
    相关资源
    最近更新 更多