我有一个 QMainWindow 有各种小部件,加载了 loadUI。其中一个小部件是一个 QGroupBox,它在开始时是空的(也没有布局)。我还有一个自定义小部件 (CustomWidgetContainer),它在其内部创建各种小部件 (CustomWidget)。有多少和哪个是在运行时确定的。
问题是 CustomWidgetContainer 有自己的布局来添加它的小部件。但是当 CustomWidgetContainer 被添加到 QMainWindow 时,布局将替换为 QMainWindow 的父级布局(这是预期的和记录的行为)。
但是当这个 CustomWidgetContainer 需要自己的布局 (self.layout()) 来添加额外的 CustomWidgets 或删除所有 CustomWidgets 时,self.layout() 返回 None。
我可以想象各种解决方法检查父级是否已经有一个布局(使用那个,在父级中设置一个等)等等。但是我不想对我的孩子(CustomWidgetContainer)类的父母(QMainWindow)做任何事情,因为我认为这是一种不好的做法。
片段:ScalarInputEdit == CustomWidget,InputsWidget == CustomWidgetContainer
class MainWindow(qt.QMainWindow):
....
def connect(self, host, port):
self._client = PymotClient(host, port)
self.client.connect()
self._set_enabled_connected()
self.log.info("Connected to %s:%d", host, port)
self._inputswidget = InputsWidget(self, self.client)
print "Layout Before:", self._inputswidget.layout()
self.inputsBox.setLayout(self._inputswidget.layout())
print "Layout After:", self._inputswidget.layout()
self._inputswidget.append_inputs_from_client()
class InputsWidget(qt.QWidget):
def __init__(self, parent, client):
super(InputsWidget, self).__init__(parent)
....
self.setLayout(qt.QGridLayout())
def append_inputs_from_client(self):
for inp in some_list:
self.append_input(inp)
def append_input(self, pbo):
self.layout().addWidget(ScalarInputEdit(self, self.client, pbo))
def remove_all_inputs(self):
for child in self.layout().children():
child.deleteLater()
输出:
Layout Before: <PyQt4.QtGui.QGridLayout object at 0x8880ecc>
Layout After: None
Exception:
File "...inputwidgets.py", line 134, in append_input
self.layout().addWidget(ScalarInputEdit(self, self.client, pbo))
AttributeError: 'NoneType' object has no attribute 'addWidget'
这样做的标准/良好做法是什么?对我来说,在以后的某个阶段(在 __ init__ 之后)需要您的 layout() 似乎很常见。但是由于某些用例似乎取代了我的布局,或者更糟糕的是甚至将其删除,我如何确定要添加/删除的布局?