Wyczyść wszystkie widżety w układzie w pyqt
Czy istnieje sposób na wyczyszczenie (usunięcie) wszystkich widżetów w układzie?
self.plot_layout = QtGui.QGridLayout()
self.plot_layout.setGeometry(QtCore.QRect(200,200,200,200))
self.root_layout.addLayout(self.plot_layout)
self.plot_layout.addWidget(MyWidget())
Teraz chcę zastąpić widget w {[1] } nowym widgetem. Czy istnieje łatwy sposób na wyczyszczenie wszystkich widżetów w plot_layout
? Nie widzę takiej metody.
11 answers
Po wielu badaniach (a to zajęło sporo czasu, więc dodaję go tutaj dla przyszłych odniesień), w ten sposób znalazłem naprawdę jasne i Usuń widgety w układzie:
for i in reversed(range(layout.count())):
layout.itemAt(i).widget().setParent(None)
Co dokumentacja mówi o QWidget czy to:
Nowy widżet jest usuwany, gdy jego rodzic jest usuwany.
Ważna uwaga: musisz zapętlić do tyłu, ponieważ usuwanie rzeczy od początku zmienia elementy i zmienia kolejność elementów w układzie.
Aby sprawdzić i potwierdzić, że układ jest pusty:
for i in range(layout.count()): print i
Wydaje się, że jest na to inny sposób. Zamiast używać funkcji setParent, użyj funkcji deleteLater () w następujący sposób:
for i in reversed(range(layout.count())):
layout.itemAt(i).widget().deleteLater()
Dokumentacja mówi, że QObject.deleteLater (self)
Rozkłada ten obiekt do usunięcia.
Jednakże, jeśli uruchomisz kod testowy określony powyżej, wyświetli on pewne wartości. Oznacza to, że układ nadal zawiera elementy, w przeciwieństwie do kodu z setParent .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-11 02:42:23
To może być trochę za późno, ale po prostu chciałem dodać to dla przyszłych odniesień:
def clearLayout(layout):
while layout.count():
child = layout.takeAt(0)
if child.widget():
child.widget().deleteLater()
Zaadaptowane z Qt docs http://doc.qt.io/qt-5/qlayout.html#takeAt. pamiętaj, że gdy usuwasz elementy potomne z układu za jakiś czas lub w pętli for, skutecznie modyfikujesz indeks # każdego elementu potomnego w układzie. Dlatego napotkasz problemy używając pętli for i in range()
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-11 12:21:23
Odpowiedź od PALEN działa dobrze, jeśli nie musisz dodawać nowych widżetów do układu.
for i in reversed(range(layout.count())):
layout.itemAt(i).widget().setParent(None)
Ale dostaniesz "Segmentation fault (core dumped)" w pewnym momencie, jeśli opróżnisz i wypełnisz układ wiele razy lub wieloma widżetami. Wygląda na to, że układ utrzymuje listę widżetów i że ta lista jest ograniczona pod względem rozmiaru.
Jeśli usuniesz widżety w ten sposób:
for i in reversed(range(layout.count())):
widgetToRemove = layout.itemAt(i).widget()
# remove it from the layout list
layout.removeWidget(widgetToRemove)
# remove it from the gui
widgetToRemove.setParent(None)
Nie dostaniesz tego problemu.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-24 18:23:27
Tak czyszczę layout:
def clearLayout(layout):
if layout is not None:
while layout.count():
child = layout.takeAt(0)
if child.widget() is not None:
child.widget().deleteLater()
elif child.layout() is not None:
clearLayout(child.layout())
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-03-07 23:25:33
Możesz użyć close()
Metody widget
:
for i in range(layout.count()): layout.itemAt(i).widget().close()
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-28 16:28:15
Używam:
while layout.count() > 0:
layout.itemAt(0).setParent(None)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-08 15:57:37
Moim rozwiązaniem tego problemu jest nadpisanie metody setLayout programu QWidget. Poniższy kod aktualizuje układ do nowego układu, który może lub nie może zawierać elementów, które są już wyświetlane. Możesz po prostu utworzyć nowy obiekt układu, dodać do niego cokolwiek chcesz, a następnie wywołać setLayout. Oczywiście możesz również po prostu zadzwonić do clearLayout, aby usunąć wszystko.
def setLayout(self, layout):
self.clearLayout()
QWidget.setLayout(self, layout)
def clearLayout(self):
if self.layout() is not None:
old_layout = self.layout()
for i in reversed(range(old_layout.count())):
old_layout.itemAt(i).widget().setParent(None)
import sip
sip.delete(old_layout)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-19 00:38:06
From the docs:
Aby usunąć widżet z układu, wywołaj
removeWidget()
. WywołanieQWidget.hide()
na widżecie również skutecznie usuwa widżet z układu do momentu wywołaniaQWidget.show()
.
removeWidget
jest dziedziczona z QLayout
, dlatego nie jest wymieniona wśród metod QGridLayout
.
Kilka rozwiązań, jeśli zamieniasz się między znanymi widżetami za pomocą ułożonego widżetu i po prostu przerzucasz pokazany indeks może być o wiele łatwiejsze niż dodawanie i usuwanie pojedynczych widżetów z układu.
Jeśli chcesz zastąpić Wszystkie potomkami widżetu, to QObject
funkcje findChildren
powinny cię tam znaleźć np. Nie wiem, w jaki sposób funkcje szablonu są zawinięte w pyqt. Ale możesz również wyszukiwać widżety po nazwie, jeśli je znasz.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-25 16:42:00
To mój pierwszy raz w rzeczywistości odpowiadając na pytanie przepełnienie stosu, ale zobaczyłem, że wszystkie odpowiedzi tutaj są nieco błędne. (tak, Wiem, że pytanie było, aby usunąć wszystkie widżety) problem z większością z nich jest to, że nie stanowią one zagnieżdżone układy, więc zrobiłem funkcję rekurencyjną, że biorąc pod uwagę układ będzie rekurencyjnie usunąć wszystko wewnątrz niego, i wszystkie układy wewnątrz niego. tutaj jest:
def clearLayout(layout):
print("-- -- input layout: "+str(layout))
for i in reversed(range(layout.count())):
layoutItem = layout.itemAt(i)
if layoutItem.widget() is not None:
widgetToRemove = layoutItem.widget()
print("found widget: " + str(widgetToRemove))
widgetToRemove.setParent(None)
layout.removeWidget(widgetToRemove)
elif layoutItem.spacerItem() is not None:
print("found spacer: " + str(layoutItem.spacerItem()))
else:
layoutToRemove = layout.itemAt(i)
print("-- found Layout: "+str(layoutToRemove))
clearLayout(layoutToRemove)
Mogłem nie uwzględnić wszystkich typów interfejsu użytkownika, nie jestem pewien. Hope this pomaga!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-05 03:09:12
for i in reversed (range(layout.count())):
layout.itemAt(i).widget().close()
layout.takeAt(i)
Lub
for i in range(layout.count()):
layout.itemAt(0).widget().close()
layout.takeAt(0)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-15 23:15:07