在小部件 PyQt5 上设置布局后更改布局

Posted

技术标签:

【中文标题】在小部件 PyQt5 上设置布局后更改布局【英文标题】:Changing a layout after it has been set on a widget PyQt5 【发布时间】:2020-09-09 17:36:24 【问题描述】:

我有一个 QStackedWidget 对象,其中添加了三个不同的 QWidget。我为每一个初始化布局,并在程序启动时相应地设置它们。然而,当用户操作来自一个的数据时,另一个表示的数据可能会发生变化。我已经编写了工作函数来在状态更改时更改布局,但它永远不会从第一次发生 QWidget.setLayout() 调用时设置的布局更新。

class UI(self):
    def __init__(self):
        #create baseLayout
        #create emptyLayout
        self.layout = baseLayout

    def updateLayout(self):
        if empty:
            self.layout = emptyLayout
        else:
            self.layout = baseLayout

class MainWindow(self):
    def __init__(self, UI):
        self.centerWidget = QStackedWidget()
        self.childWidget = QWidget()
        self.childWidget.setLayout(UI.layout)
        self.centerWidget.addWidget(childWidget)

所以在上面的例子中,如果调用 updateLayout() 函数并将 UI 的布局更改为 emptyLayout,它不会改变选择 childWidget 时的显示方式。

我想 .setLayout 并不是要随着布局本身的变化而更新,但是还有其他方法可以解决这个问题吗?我仍然只有几个月的时间进入 PyQt5 并且不是它的大师,所以如果有更好的方法来做到这一点,我会全力以赴。

编辑:我在这个小型博客网站上遇到了答案,所以我在这里分享。 https://myprogrammingnotes.com/remove-layout.html

不足之处在于 QLayout 的复制构造函数是私有的,找到保存对布局的引用的方法远非易事。他建议以这种方式设置所需的布局以附加到它们自己的小部件,然后使用 .setVisible() 来“打开或关闭它们”。

这样做可能会很快失控并变得难以遵循,但就我而言,它很好,并且不需要多种新方法,因为我只在两个地方需要它。

【问题讨论】:

请提供minimal reproducible example 用一个粗略的例子编辑 【参考方案1】:

您的问题与this非常相似

在布局中删除

item=self.layout.takeAt(#widgetitem index to take out)
self.layout.removeItem(item)

添加布局

self.layout.addItem(QLabel("new item"))

在布局中添加布局

self.layout.addLayout(baseLayout) # to add into a layout (make sure if its horizontally layout or vertical layout because it will be added accordingly 

删除布局 参考这个Question

【讨论】:

我不完全确定我是否遵循。您是说从一种布局更改为另一种布局的正确方法是删除当前布局,然后添加新布局? 是的,这就是我目前所知道的。可能还有其他方法,但这是我认为最安全的方法。 所以我实现了这个,虽然它在我第一次从一个布局到另一个布局时工作,但之前的布局因为已被删除而无法访问。我尝试事先对布局进行参考,以便可以再次使用它,但这似乎也不起作用。 你能写一个伪代码你如何改变函数的布局?因为当您引用布局时,它可能会替换旧布局。您是否尝试将布局保存在列表中? listLayout.append(layout1) 并且每次都像这样分配 self.layout.addLayout(listLayout[0]) 我确实试过了。最初我只是使用 self.layout.addLayout(self.baseLayout) 无论哪种方式它都会给出相同的结果。在看到每个布局后,因为所有布局项目都已被删除,所以什么都没有出现。有没有什么方法可以在不先从布局中删除小部件的情况下清除布局?

以上是关于在小部件 PyQt5 上设置布局后更改布局的主要内容,如果未能解决你的问题,请参考以下文章

Android在小部件内获取textView值

PyQt5 - 动态添加小部件到布局

尽管更新了小部件,但 Pyqt5 更新的小部件未添加到布局中

QPushButton 更改同一布局中其他小部件的边距

如何使用 QMenuBar 在小部件之间切换?

如何在 PyQt5 布局中更紧密地对齐两个小部件?