Reputation: 1721
When I drag to resize window in Qt, it is stretching the widgets inside my QVBoxLayout. I would like to avoid this.
Here are a few pictures of the demo app (created for this stackoverflow post):
How can I use Qt Layouts, or other Qt Widget classes to solve this problem? Here is the code for my Demo app (about 50 lines):
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, \
QGroupBox, QGridLayout, QLabel, QScrollArea
from typing import List
class AccountWidget(QWidget):
def __init__(self, data: dict, parent=None):
super().__init__(parent)
self.group_box_layout = QGridLayout()
for i, (key, value) in enumerate(data.items()):
self.group_box_layout.addWidget(QLabel(key), i+1, 1)
self.group_box_layout.addWidget(QLabel(value), i+1, 2)
self.group_box = QGroupBox()
self.group_box.setLayout(self.group_box_layout)
self.main_layout = QVBoxLayout()
self.main_layout.addWidget(self.group_box)
self.setLayout(self.main_layout)
class AccountListWidget(QWidget):
def __init__(self, data: List[dict], parent=None):
super().__init__(parent)
self.main_layout = QVBoxLayout()
for account_data in data:
self.main_layout.addWidget(AccountWidget(account_data))
self.setLayout(self.main_layout)
class MainWidget(QWidget):
def __init__(self, data: List[dict], parent=None):
super().__init__(parent)
self.account_list_widget = AccountListWidget(data)
self.scroll_area = QScrollArea()
self.scroll_area.setWidgetResizable(True)
self.scroll_area.setWidget(self.account_list_widget)
self.main_layout = QVBoxLayout()
self.main_layout.addWidget(self.scroll_area)
self.setLayout(self.main_layout)
if __name__ == "__main__":
app = QApplication(sys.argv)
data = [{"created":"2019","balance":"100","deposits":"50","type":"Chq"},
{"created":"2020","balance":"80","deposits":"45","type":"Chq"},
{"created":"2020","balance":"70","deposits":"55","type":"Sav"}]
mainWidget = MainWidget(data)
mainWindow = QMainWindow()
mainWindow.setCentralWidget(mainWidget)
mainWindow.setWindowTitle("Demo App")
mainWindow.resize(300, 300)
mainWindow.show()
app.exec()
Upvotes: 2
Views: 7380
Reputation: 48489
Just add a stretch to the bottom of the layout (this is only possible for boxed layout):
class AccountListWidget(QWidget):
def __init__(self, data: List[dict], parent=None):
# ...
self.main_layout.addStretch()
If you need to do something like this on a grid layout, you can add a QSpacerItem or a single empty QWidget with its size policy set to expanded:
spacer = QtWidgets.QWidget()
spacer.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanded)
gridLayout.addWidget(spacer, gridLayout.rowCount(), 0)
Another solution is to set the size policy to the container (instead of adding the stretch):
class AccountListWidget(QWidget):
def __init__(self, data: List[dict], parent=None):
# ...
self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum)
A couple of suggestions:
AccountWidget
only contains a QGroupBox, so you should probably just subclass from QGroupBox instead;layout.setContentsMargins
;Upvotes: 12