Reputation: 1262
I'm trying to build a QGridLayout with stretchable-width columns but non-stretchable-height rows. The grid in inside a QScrollArea, and with the exception of the height, it's almost working. You can see it in the following images:
As you can see, the rows are being vertically stretched. I would like all the rows to be equal and to not fit all the parent's height if there are too few rows (first image). Should I touch the grid or the actual widgets?
Edit: reproducible example
import sys
from PyQt5.QtWidgets import (QWidget, QGridLayout, QLabel, QRadioButton, QApplication, QScrollArea, QVBoxLayout)
class ScrollableGrid(QWidget):
def __init__(self, columnSpans, minimumColumnWidth):
super().__init__()
# Grid
self.grid = QWidget()
self.gridLayout = QGridLayout()
for i in range(len(columnSpans)):
self.gridLayout.setColumnStretch(i, columnSpans[i])
self.gridLayout.setColumnMinimumWidth(i, columnSpans[i] * minimumColumnWidth)
self.grid.setLayout(self.gridLayout)
# Scroll area
self.scrollArea = QScrollArea()
self.scrollArea.setWidget(self.grid)
self.scrollArea.setWidgetResizable(True)
# Compute the correct minimum width
width = (self.grid.sizeHint().width() +
self.scrollArea.verticalScrollBar().sizeHint().width() +
self.scrollArea.frameWidth() * 2)
self.scrollArea.setMinimumWidth(width)
# Layout
self.layout = QVBoxLayout()
self.layout.addWidget(self.scrollArea)
self.setLayout(self.layout)
def addRow(self, row, elements):
for column in range(len(elements)):
self.gridLayout.addWidget(elements[column], row, column)
class MainWindow(QWidget):
def __init__(self):
super().__init__()
# ScrollableGrid
self.grid = ScrollableGrid(columnSpans=[1,2,3], minimumColumnWidth=100)
# Add rows
for i in range(3):
self.grid.addRow(i, [QLabel('A'), QLabel('B'), QRadioButton()])
# Window layout
self.layout = QVBoxLayout()
self.layout.addWidget(self.grid)
self.setLayout(self.layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
windowExample = MainWindow()
windowExample.show()
sys.exit(app.exec_())
Upvotes: 1
Views: 103
Reputation: 13651
void QGridLayout::setRowStretch(int row, int stretch)
Sets the stretch factor of row row to stretch. The first row is number 0.
The stretch factor is relative to the other rows in this grid. Rows with a higher stretch factor take more of the available space.
Yes, is it because it must me called after all rows have been added.
import sys
from PyQt5.QtWidgets import (QWidget, QGridLayout, QLabel, QRadioButton,
QApplication, QScrollArea, QVBoxLayout)
class ScrollableGrid(QWidget):
def __init__(self, columnSpans, minimumColumnWidth):
super().__init__()
# Grid
self.grid = QWidget()
self.gridLayout = QGridLayout()
for i in range(len(columnSpans)):
self.gridLayout.setColumnStretch(i, columnSpans[i])
self.gridLayout.setColumnMinimumWidth(i, columnSpans[i] * minimumColumnWidth)
self.grid.setLayout(self.gridLayout)
# Scroll area
self.scrollArea = QScrollArea()
self.scrollArea.setWidget(self.grid)
self.scrollArea.setWidgetResizable(True)
# Compute the correct minimum width
width = (self.grid.sizeHint().width() +
self.scrollArea.verticalScrollBar().sizeHint().width() +
self.scrollArea.frameWidth() * 2)
self.scrollArea.setMinimumWidth(width)
# Layout
self.layout = QVBoxLayout()
self.layout.addWidget(self.scrollArea)
self.setLayout(self.layout)
def addRow(self, row, elements):
for column in range(len(elements)):
self.gridLayout.addWidget(elements[column], row, column)
class MainWindow(QWidget):
def __init__(self):
super().__init__()
# ScrollableGrid
self.grid = ScrollableGrid(columnSpans=[1,2,3], minimumColumnWidth=100)
# Add rows
for i in range(3):
self.grid.addRow(i, [QLabel('A'), QLabel('B'), QRadioButton()])
self.grid.gridLayout.setRowStretch(111, 1) # !!!
# Window layout
self.layout = QVBoxLayout()
self.layout.addWidget(self.grid)
self.setLayout(self.layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
windowExample = MainWindow()
windowExample.show()
sys.exit(app.exec_())
Upvotes: 1