我有一个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()似乎很常见。但是,由于某些用例似乎取代了我的布局,甚至更糟糕的是删除它,我如何确定要添加/删除的布局?
答案 0 :(得分:0)
引用:
when the CustomWidgetContainer gets added to the QMainWindow, the layout is
replaced with the parenting layout of the QMainWindow (which is expected and
documented behaviour).
这对我来说非常不清楚:你指的是记录在案的行为?
self._inputswidget = InputsWidget(self, self.client)
print "Layout Before:", self._inputswidget.layout()
self.inputsBox.setLayout(self._inputswidget.layout())
为什么要将inputsBox
的布局设置为_inputswidget
的布局?
print "Layout After:", self._inputswidget.layout()
_inputswidget
的布局现在很自然是None
,因为您只是将转移到inputsBox
。
self._inputswidget.append_inputs_from_client()
显然,这不起作用,因为你取消了_inputswidget
的布局,并没有取代它。