2

我有一个 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() 似乎很常见。但是由于某些用例似乎取代了我的布局,或者更糟糕的是甚至将其删除,我如何确定要添加/删除的布局?

4

1 回答 1

1

引用:

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,并没有替换它。

于 2012-11-13T17:28:00.120 回答