Adding/Removing PyQt5 上的 QSlider 小部件

Adding/Removing QSlider widgets on PyQt5

我想根据 QStandardItemModel 结构中检查项目的数量动态更改我的应用程序 window 上的滑块数量。

我的应用程序 window 有一个名为 slidersQVBoxLayout 实例,我会在按下按钮时更新它:

首先删除所有滑块最终在那里:

self.sliders.removeWidget(slider)

然后创建一个新集。

相关代码:

def create_sliders(self):
    if len(self.sliders_list):
        for sl in self.sliders_list:
            self.sliders.removeWidget(sl)
    self.sliders_list = []
    for index in range(self.model.rowCount()):
        if self.model.item(index).checkState():
            slid = QSlider(Qt.Horizontal)
            self.sliders.addWidget(slid)
            self.sliders_list.append(slid)

这个原理似乎可行,但是发生的事情很奇怪,因为删除的滑块并没有真正消失,而是从底层布局中 'disconnected' 原样消失。

创建后,滑块在我调整主元素大小时保持它们在其他元素中的位置 window。 然而,一旦它们被移除,它们就会占据一个固定的位置,例如,如果我减小 window 的大小,它们就会消失。 不幸的是,我在 linking 图像方面遇到困难(它说当我尝试从粘贴板 link 时不支持格式),所以我希望这个描述足以突出问题。

我是否必须使用不同的程序移除滑块?

编辑

感谢@eyllansec 的回复,它浓缩了围绕该主题的一系列其他回复,我无法找到这些回复,因为我不知道方法 deleteLater() 这是获取的关键删除 QLayout.

中的小部件

我将它标记为我的选择(嘿,它是唯一的,毕竟它有效!),但是我想提出我自己的代码,它也可以在最小的变化下工作 w.r.t。按照我一开始提出的建议。

这里的关键点是我使用的方法 QLayout.removeWidget(QWidget) 我错误地认为,它会..呃..删除小部件!但实际上它所做的是(如果我理解正确的话)将其从布局实例中移除

这就是为什么它仍然挂在我的 window 中的原因,尽管它似乎已断开连接

Manual reference

此外,建议的代码比我需要的更通用,因为它是对布局内容的递归,原则上可以是其他 QLayout 对象或 QWidgets(甚至Qspacer),并按层次结构组织(即 QLayout 中的 QWidget QLayout,依此类推)。

check this other answer

从那里开始,递归的使用和一系列 if-then 构造。

虽然我的情况要简单得多,因为我使用这个 QVLayout 实例来放置我的 QSliders,这就是全部。所以,对我来说,我现在坚持我的清单,因为我不喜欢 QLayout.TakeAt(n) 的形式主义,我不需要它。我很高兴我在列表中构建的引用绝对可以使用。

最后,在这种情况下,这是对我有用的稍微改动过的代码:

def create_sliders(self):
    if len(self.sliders_list):
        for sl in self.sliders_list:
            sl.deleteLater()
    self.sliders_list = []
    for index in range(self.model.rowCount()):
        if self.model.item(index).checkState():
            slid = QSlider(Qt.Horizontal)
            self.sliders.addWidget(slid)
            self.sliders_list.append(slid)

不必将滑块保存在列表中,可以通过包含滑块的布局访问它们。我已经实现了一个删除布局中元素的功能。解决方法如下:

def create_sliders(self):
    self.clearLayout(self.sliders)

    for index in range(self.model.rowCount()):
        if self.model.item(index).checkState():
            slid = QSlider(Qt.Horizontal)
            self.sliders.addWidget(slid)

def clearLayout(self, layout):
    if layout:
        while layout.count():
            item = layout.takeAt(0)
            widget = item.widget()
            if widget:
                widget.deleteLater()
            else :
                self.clearLayout(item.layout())
            layout.removeItem(item)