Добавление / удаление виджетов QSlider на PyQt5
Я хочу динамически изменять количество ползунков в окне приложения в зависимости от количества отмеченных элементов в 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)
о котором я ошибочно думал, это было бы.. ээ.. Убрать виджет! Но на самом деле он делает (если я правильно понял) удалить его из экземпляра макета.
Вот почему он все еще висел в моем окне, хотя казалось, что он отключен
Кроме того, предлагаемый код является гораздо более общим, чем то, что мне нужно, так как это рекурсия содержимого макета, которая в принципе может быть и другой QLayout
объекты или QWidgets
(или даже Qspacer
) и быть организованы в иерархию (т.е. QWidget
QLayout
в пределах QLayout
и так далее).
Оттуда, использование рекурсии и серии 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)
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)