何时在PySide中设置父级

Cor*_*y-G 3 python garbage-collection reference parent-child pyside

在网上的任何地方,我似乎都找不到太多有关此问题的指导。我一直在学习PySide,并且注意到那里的一半示例只是将parentQStuff 设置为,None而其他示例会将其设置为一个对象。我意识到可能有一个垃圾回收问题在起作用。假设我有一个QWidget对象,我创建了一个QThing并将其引用parent为QWidget,然后.add将QThing引用为QWidget。看来我那时应该在某处有循环引用。Python会引用计数,因此这将意味着对象不会被垃圾收集。甚至像

self.addWidget(QLabel('label', self))

会导致循环引用(尽管我想这个案例是由PySide处理的。)也许我太担心了,所有这些都已处理,我不知道。

简而言之:在PySide中使用父母的正确方法是什么?

Tri*_*ion 5

这里有两件事在起作用:

t

Qt通过关系将其对象组织在对象树中。当您放置一个对象时,所有子代也会被破坏(在C侧)。诸如样式之类的属性也通过该关系继承。事实证明,这对于GUI对象非常有用,毕竟,当您关闭对话框时,您可能还希望摆脱对话框中的按钮。

另请参阅对象树和所有权

Python(CPython)

当对象超出范围时,Python会自动删除它们。例如,您认为自己已经消失的按钮是因为Python垃圾已经收集了它们。事实证明,在任何地方正确设置父级都会有所帮助。例如,对于布局,最简单的方法是在布局的构造中直接指定父项(保存对的调用setLayout)。

但是,例如,如果您仍具有对按钮的python引用,但该小部件已被Qt破坏,则可能会收到“ RuntimeError:内部C ++对象已被删除”。

因此,设置父母的足够程度有助于使用Qt和Python编写无错误代码。

在您的示例中:

self.addWidget(QLabel('label', self))
Run Code Online (Sandbox Code Playgroud)

父级设置两次。首先QLabel('label', self)是创建内部部件,然后是何时addWidget调用(请参阅参考资料QLayout)。为何不做两次相同的事情,为什么不做一次呢?

self.addWidget(QLabel('label'))
Run Code Online (Sandbox Code Playgroud)

有关本身的循环引用,请参阅我是否应该担心Python中的循环引用?