父参数 (PySide) 从何而来?

From where comes the parent argument (PySide)?

在这个例子中,parent参数从何而来,谁提供的?

class MainWindow(QtGui.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()

        self.do_something() #sanity check
        self.cw = ChildWidget(self)
        self.setCentralWidget(self.cw)
        self.show()

    def do_something(self):
        print 'doing something!'


class ChildWidget(QtGui.QWidget):
    def __init__(self, parent):
        super(ChildWidget, self).__init__(parent)

        self.button1 = QtGui.QPushButton()
        self.button1.clicked.connect(self.do_something_else)

        self.button2 = QtGui.QPushButton()
        self.button2.clicked.connect(self.parent().do_something)

        self.layout = QtGui.QVBoxLayout()
        self.layout.addWidget(self.button1)
        self.layout.addWidget(self.button2)
        self.setLayout(self.layout)
        self.show()

    def do_something_else(self):
        print 'doing something else!'

Parent 和 children 特定于 Qt (C++)。来自 doc of QObject:

QObjects organize themselves in object trees. When you create a QObject with another object as parent, the object will automatically add itself to the parent's children() list. The parent takes ownership of the object; i.e., it will automatically delete its children in its destructor.

QWidget 和许多其他 class 继承自 QObject,因此它也适用于它们。对于每个 children,parent() 方法 returns 一个指向 parent object 的指针。

基本上,您使用 parent 创建小部件,以便可以正确删除它们。 通常情况下,您的主要 window 是所有小部件的 parent - 或 grandparent:当您关闭 window 时,所有内容都会按正确的顺序删除。


根据您的评论,我认为您也对 super() 的使用感到困惑。它调用小部件的parent。

另一种写法:

class ChildWidget(QtGui.QWidget):
    def __init__(self, parent):
        super(ChildWidget, self).__init__(parent)

就是直接调用QWidget的init方法:

class ChildWidget(QtGui.QWidget):
    def __init__(self, parent):
        QtGui.QWidget.__init__(parent)

ChildWidget 继承自 QWidget(这就是我们定义 class 的方式)。在init方法中,需要调用QWidget的默认构造函数。否则你将无法使用 QWidget 的默认方法和属性(试试看...)。
如果给定 parent,它也会相应地组织自己。它会将自己添加到 parent children 方法中,并保留对其 parent.

的引用