65 votes

Effacer tous les widgets dans une disposition dans pyqt

Existe-t-il un moyen d'effacer (supprimer) tous les widgets d'une mise en page ?

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())

Maintenant, je veux remplacer le widget dans plot_layout avec un nouveau widget. Existe-t-il un moyen simple d'effacer tous les widgets de l'application plot_layout ? Je ne vois pas de méthode de ce type.

7voto

SoloPilot Points 319

J'utilise :

    while layout.count() > 0: 
        layout.itemAt(0).setParent(None)

4voto

C'est la première fois que je réponds à une question de stack overflow mais j'ai vu que toutes les réponses sont légèrement fausses. (oui, je sais que la question était de supprimer tous les widgets) Le problème avec la plupart d'entre elles est qu'elles ne prennent pas en compte les mises en page imbriquées, donc j'ai créé une fonction récursive, qui, étant donné une mise en page, supprimera récursivement tout ce qui se trouve à l'intérieur, et toutes les mises en page à l'intérieur :

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)

Je n'ai peut-être pas pris en compte tous les types d'interface utilisateur, je ne suis pas sûr. J'espère que cela vous aidera !

3voto

joshua Points 836

Ma solution à ce problème consiste à remplacer la méthode setLayout de QWidget. Le code suivant met à jour la disposition vers la nouvelle disposition qui peut ou non contenir des éléments déjà affichés. Vous pouvez simplement créer un nouvel objet layout, y ajouter ce que vous voulez, puis appeler setLayout. Bien entendu, vous pouvez également appeler clearLayout pour tout supprimer.

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)

2voto

Dans la documentation :

Pour supprimer un widget d'une mise en page, appelez la fonction removeWidget() . Appeler QWidget.hide() sur un widget supprime aussi effectivement le widget de la disposition jusqu'à ce que QWidget.show() s'appelle.

removeWidget est hérité de QLayout c'est pourquoi il n'est pas listé parmi les QGridLayout méthodes.

2voto

user1021810 Points 1

J'ai eu des problèmes avec les solutions mentionnées précédemment. Il y avait des widgets persistants qui causaient des problèmes ; je soupçonne que la suppression était programmée, mais pas terminée. J'ai également dû définir le parent des widgets sur Aucun. Voici ma solution :

def clearLayout(layout):
    while layout.count():
        child = layout.takeAt(0)
        childWidget = child.widget()
        if childWidget:
            childWidget.setParent(None)
            childWidget.deleteLater()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X