I would like to create a bunch of QcheckBox with a QgridLayout inside a QscrollArea, and I need to modify the number of Checkbox of the QGridLayout.
My issue is when I increase the number of check boxes, they are compressed inside the QscrollArea instead of creating a scrollBar at the right side.
Here is my simple example:
import sys
import numpy as np
from PyQt6.QtGui import *
from PyQt6.QtCore import *
from PyQt6.QtWidgets import *
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__()
self.centralWidget = QWidget()
self.setCentralWidget(self.centralWidget)
self.mainHBOX = QVBoxLayout()
layout_toApply = QGroupBox('Checkboxes')
self.layout_toApply_V = QVBoxLayout()
self.grid_toApply_V = QGridLayout()
self.Stimulation_NbSources_Edit =QLineEdit('100')
self.Stimulation_NbSources_PB =QPushButton('Apply')
self.ChangeNBSource_fun()
layout_toApply.setLayout(self.layout_toApply_V)
self.layout_toApply_V.addLayout(self.grid_toApply_V)
self.layout_toApply_V.addWidget(self.Stimulation_NbSources_Edit)
self.layout_toApply_V.addWidget(self.Stimulation_NbSources_PB)
self.mainHBOX.addWidget(layout_toApply)
self.mainHBOX_W = QWidget()
self.mainHBOX_W.setLayout(self.mainHBOX)
self.widgetparam_w = QWidget()
layout_toApplyparam_w = QHBoxLayout()
self.widgetparam_w.setLayout(layout_toApplyparam_w)
self.scrolltoparam_w = QScrollArea(self.widgetparam_w)
self.scrolltoparam_w.setWidget(self.mainHBOX_W)
self.mainlay = QHBoxLayout()
self.mainlay.addWidget(self.scrolltoparam_w)
self.centralWidget.setLayout(self.mainlay)
self.centralWidget.setFixedSize(QSize(500,500))
self.Stimulation_NbSources_PB.clicked.connect(self.ChangeNBSource_fun)
def ChangeNBSource_fun(self):
for i in reversed(range(self.grid_toApply_V.count())):
widgetToRemove = self.grid_toApply_V.itemAt(i).widget()
widgetToRemove.setParent(None)
widgetToRemove.deleteLater()
N = int(self.Stimulation_NbSources_Edit.text())
nb_column = 10
nb_line = int(np.ceil(N / nb_column))
self.Apply_to_pop = []
for l in np.arange(nb_line):
for c in np.arange(nb_column):
idx = (l) * nb_column + c + 1
if idx <= N:
CB = QCheckBox(str(idx - 1))
CB.setFixedWidth(int(30))
CB.setChecked(False)
self.grid_toApply_V.addWidget(CB, l, c)
self.Apply_to_pop.append(CB)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())
Here's when I launch the code :
And here's what I get when I double the number of Check Boxes:
The QCheckBox
widgets get compressed because QScrollArea
's widget doesn't have a layout that can grow in size beyond QScrollArea
's visible boundaries.
You should set the grid layout on a widget and then set it to be the child of QScrollArea
. Make sure that QScrollArea
has QSizePolicy.Expanding
to allow it to expand.
Also set the resizing policy of QScrollArea
to QScrollArea.SetWidgetResizable(True)
import sys
import numpy as np
from PyQt6.QtGui import *
from PyQt6.QtCore import QSize
from PyQt6.QtWidgets import (
QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
QGridLayout, QGroupBox, QLineEdit, QPushButton, QCheckBox, QScrollArea
)
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__()
self.centralWidget = QWidget()
self.setCentralWidget(self.centralWidget)
self.mainHBOX = QVBoxLayout()
layout_toApply = QGroupBox('Checkboxes')
self.layout_toApply_V = QVBoxLayout()
self.grid_toApply_V = QGridLayout()
self.Stimulation_NbSources_Edit = QLineEdit('100')
self.Stimulation_NbSources_PB = QPushButton('Apply')
self.scrollContent = QWidget()
self.scrollContent.setLayout(self.grid_toApply_V)
self.scrollArea = QScrollArea()
self.scrollArea.setWidgetResizable(True)
self.scrollArea.setWidget(self.scrollContent)
layout_toApply.setLayout(self.layout_toApply_V)
self.layout_toApply_V.addWidget(self.scrollArea)
self.layout_toApply_V.addWidget(self.Stimulation_NbSources_Edit)
self.layout_toApply_V.addWidget(self.Stimulation_NbSources_PB)
self.mainHBOX.addWidget(layout_toApply)
self.centralWidget.setLayout(self.mainHBOX)
self.centralWidget.setFixedSize(QSize(500, 500))
self.Stimulation_NbSources_PB.clicked.connect(self.ChangeNBSource_fun)
self.ChangeNBSource_fun()
def ChangeNBSource_fun(self):
for i in reversed(range(self.grid_toApply_V.count())):
widgetToRemove = self.grid_toApply_V.itemAt(i).widget()
if widgetToRemove:
widgetToRemove.setParent(None)
widgetToRemove.deleteLater()
N = int(self.Stimulation_NbSources_Edit.text())
nb_column = 10
nb_line = int(np.ceil(N / nb_column))
self.Apply_to_pop = []
for l in range(nb_line):
for c in range(nb_column):
idx = l * nb_column + c + 1
if idx <= N:
CB = QCheckBox(str(idx - 1))
CB.setFixedWidth(30)
CB.setChecked(False)
self.grid_toApply_V.addWidget(CB, l, c)
self.Apply_to_pop.append(CB)
self.scrollContent.setMinimumSize(nb_column * 30, nb_line * 30)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())