[PySide] GridLayout with Scroll Area: dynamically changing content is forced into same vertical space as originally-generated comment



  • PySide, Python 3.41

    Hello -- I have a GUI which includes a GridLayout with a scrollArea. The contents of the GridLayout change dynamically based on the user's selection from a ComboBox.

    The problem: when I re-populate the Scrolled gridLayout with new content, it tries to squeeze/spread the new content into the same vertical space that was occupied by the originally-generated content. (In other words: if I start with a list containing 5 items, then I switch to a list containing 20 items, all of the 20 items will be mashed together in the same vertical space that the 5 items took.

    The contents are generated programatically from parsing data files, so I can't predict the length of the lists.

    The Question: how can I change this so that the scroll area "adapts" to the new content? I would like the distance between rows to remain constant regardless of content changes.

    Below is a -fully working example script- which demonstrates my issue.
    EDIT: My full script exceeded the maximum character count for a post. "Here is a link to the full script":https://www.dropbox.com/s/dwyz7inmxtkwdh2/ScrollQuestionForForum-SharedVersion.py?dl=0. Below are some key areas.

    Thank you!

    Here is my scrolling grid class:
    @
    class ScrollingWidget(QWidget):
    def init(self, startWith="Large", parent= None):
    '''I assume the problem is in some kind of layout/margin issue here'''
    super(ScrollingWidget, self).init()
    self.setFixedHeight(500)
    self.setFixedWidth(450)

        self.dummyData = DummyData()
    
        #Container Widget
        widget = QWidget()
        #Layout of Container Widget
        self.grid = QGridLayout(self)
        topBox = QVBoxLayout()
        bottomBox = QHBoxLayout()
    
        self.populateTopBox(topBox, startWith)
        self.populateMainContent()
    
        widget.setLayout(self.grid)
    
        scroll = QScrollArea()
        scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        scroll.setWidgetResizable(False)
        scroll.setWidget(widget)
    
        #Scroll Area Layer add
        vLayout = QVBoxLayout(self)
        vLayout.addLayout(topBox)
        vLayout.addWidget(scroll)
        vLayout.addLayout(bottomBox)
    
        self.setLayout(vLayout)
        self.repopulate()
    

    @

    And here are some of the methods involved in populating the grid:

    @
    def populateMainContent(self):
    '''Populate the main content area (the Scrolling Grid Layout)'''
    self.getPageSettings()
    for index, thingy in enumerate(self.dummyData.dataDict[self.selectedThingies]):
    rowNum = index
    newRow = EntryRow(thingy, self.dummyData, self.grid, rowNum)

            mainWidgets = newRow.createMainWidgets()
            pageWidgets = newRow.createPageWidgets(self.selectedWidgets)
    
            widgetsToShow = mainWidgets + pageWidgets
    
            newRow.displayWidgets(widgetsToShow)
    
        ### ADDING A "SPACER" ROW SEEMS TO HELP WITH THE 2nd EXAMPLE
        ### AT LEAST IT KEEPS THE SMALL LIST FROM "SPREADING OUT"
        nextRow = rowNum + 1
    
        spacerRow = QWidget()
        self.grid.addWidget(spacerRow, nextRow, 0)
        self.grid.setRowStretch(nextRow, 1)
        #########################################################
    
    def getPageSettings(self):
        '''Checks all user-selected comboboxes to determine which content to display'''
        self.selectedThingies = self.thingySelect.currentText()
        self.selectedWidgets = self.widgetSelect.currentText()
    
    def repopulate(self):
        '''Clears the grid layout and re-populates it with new content based on user selection'''
        self.clearLayout(self.grid)
        self.getPageSettings()
        self.populateMainContent()
    

    @

    Here is the EntryRow class (which may or may not be relevant?)

    @class EntryRow():
    def init(self, name, dummyData, grid, rowNum):
    '''Each row of content (name + widgets related to that name) is initialized as new "EntryRow"'''
    self.name = name
    self.widgetList = {"Main" : [],
    "theseWidgets" : [],
    "noIMeanThoseWidgets" : []
    }
    self.grid = grid
    self.rowNum = rowNum
    self.dummyData = dummyData

    def createMainWidgets(self):
        self.spinBox = QSpinBox()
        self.spinBox.setFixedWidth(15)
        self.widgetList["Main"].append(self.spinBox)
        self.nameLabel = QLabel(self.name)
        self.nameLabel.setFixedWidth(120)
        self.widgetList["Main"].append(self.nameLabel)
        return self.widgetList["Main"]
    
    def createPageWidgets(self, selectedWidgets):
        '''Creates all buttons/widgets for the EntryRow'''
        for widName in self.dummyData.widgetDict[selectedWidgets]:
            if "Button" in widName:
                newWidget = QPushButton(widName)
                newWidget.setFixedWidth(35)
            elif "Check" in widName:
                newWidget = QCheckBox(widName)
    
            self.widgetList[selectedWidgets].append(newWidget)
        return self.widgetList[selectedWidgets]
    
    def displayWidgets(self, widgetsToShow):
        for index, wid in enumerate(widgetsToShow):
            colNum = index
            self.grid.addWidget(wid, self.rowNum, colNum )@

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.