在小部件 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 上设置布局后更改布局的主要内容,如果未能解决你的问题,请参考以下文章