0

我想根据结构中选中项目的数量动态更改应用程序窗口上的滑块数量QStandardItemModel

我的应用程序窗口有一个QVBoxLayout被调用的实例,sliders当按下按钮时我会更新它:

首先最终删除所有滑块:

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)

该原理似乎有效,但是发生的事情很奇怪,因为已删除的滑块并没有真正消失,而是因为它们与底层布局“断开连接”。

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

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

编辑

感谢@eyllansec 的回复,它浓缩了围绕该主题的许多其他回复,我无法找到这些回复,因为我不知道deleteLater()摆脱QLayout.

我将它标记为我选择的(嘿,它是唯一的,毕竟它可以工作!),但是我想提出我自己的代码,它也可以对我一开始提出的内容进行最小的更改。

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

这就是为什么它仍然挂在我的窗户上,虽然它似乎断开了

手动参考

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

检查这个其他答案

从那里开始,使用递归和一系列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)
4

1 回答 1

1

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

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)
于 2017-06-10T01:17:11.460 回答