1

I have a QStackedWidget object with three different QWidgets added to it. I initialize the the layouts for each of those and set them accordingly when the program starts up. However, as the user manipulates data from one, the data represented on another may change. I have already written working functions to change the layout when the state changes, but it never updates the layout from the one that was set when the QWidget.setLayout() call first happened.

class UI(self):
    def __init__(self):
        #create baseLayout
        #create emptyLayout
        self.layout = baseLayout

    def updateLayout(self):
        if empty:
            self.layout = emptyLayout
        else:
            self.layout = baseLayout

class MainWindow(self):
    def __init__(self, UI):
        self.centerWidget = QStackedWidget()
        self.childWidget = QWidget()
        self.childWidget.setLayout(UI.layout)
        self.centerWidget.addWidget(childWidget)

So in the above example if the updateLayout() function is called and changes the UI's layout to emptyLayout, it does not change how it appears when selecting the childWidget.

I suppose .setLayout isn't meant to update as the layout itself changes, but is there some other way to pull this off? I'm still only a few months into PyQt5 and not a master at it so if there is a better way to do this I'm all ears.

EDIT: I ran across the answer on this small blog site so I'm sharing it here. https://myprogrammingnotes.com/remove-layout.html

The short of it is that the copy constructor of QLayout is private and finding ways to save references to layouts is far beyond easy. He recommends setting layouts needed this way to be attached to their own widgets and then using .setVisible() to "turn them on or off."

Doing this could get out of hand fast and become hard to follow, but for my case it's fine and works well without the need for multiple new methods since I only need it in two places.

skeletor
  • 27
  • 4

1 Answers1

1

Your question is very similar to this

To remove in a layout

item=self.layout.takeAt(#widgetitem index to take out)
self.layout.removeItem(item)

To add in a layout

self.layout.addItem(QLabel("new item"))

To add layout in a layout

self.layout.addLayout(baseLayout) # to add into a layout (make sure if its horizontally layout or vertical layout because it will be added accordingly 

to remove layout refer to this Question

Elan
  • 71
  • 9
  • I'm not entirely sure I follow. You're saying the proper way to change from one layout to another is to delete the current and then add the new layout? – skeletor Sep 09 '20 at 19:27
  • Yes thats what i know so far. may be there might be any other way around but this is the safest way i believe. – Elan Sep 09 '20 at 19:29
  • So I implemented this and while it works the first time I go from one layout to the other, afterwards the previous layout is inaccessible because it's been deleted. I tried making a reference to the layout before hand so I could use it again but that doesn't seem to work either. – skeletor Sep 10 '20 at 03:12
  • Can you write a pseudo code how are you changing layouts in functions? because there is a possibility that when you make a reference of a layout it might just replaces the old layouts. did you try saving layouts in a list? ```listLayout.append(layout1)``` and assign everytime like this ```self.layout.addLayout(listLayout[0])``` – Elan Sep 10 '20 at 13:47
  • I tried exactly that. Originally I was just using {self.layout.addLayout(self.baseLayout)} Either way it is giving the same result. After seeing each layout once nothing ever appears because all of the layouts items have been deleted. Is there not some way to clear the layout without deleting widgets from the layout first? – skeletor Sep 11 '20 at 05:18
  • Can you edit the question and post your code so i can test run it? – Elan Sep 11 '20 at 16:52