I'm developing some custom software that involves creating a workspace and working in it. I want to display all the existing workSpace directories in a dynamic scrollarea grid comprised of buttons that changes the positions of the buttons depending on the amount of screen real estate the scrollarea is taking up so that as many buttons as possible are inserted in the highest possible row.( So basically like the file explorer changes the layout of the folders and files to fit the screen in a grid depending on how you resize the window) I tried doing this using a gridlayout inside the scrollarea. I also tried to add qhboxlayouts in a qvboxlayout to no avail since I had no idea how to check whether there is space for another button to remove one from a lower qhboxlayout and append to a higher one.
This is my current code:
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QFileDialog
class Ui_AutoCal(object):
def setupUi(self, AutoCal):
AutoCal.setObjectName("AutoCal")
AutoCal.resize(513, 551)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(AutoCal.sizePolicy().hasHeightForWidth())
AutoCal.setSizePolicy(sizePolicy)
AutoCal.setCursor(QtGui.QCursor(QtCore.Qt.CrossCursor))
AutoCal.setStyleSheet("*{\n"
"background-color: rgb(54, 54, 54);\n"
"color:rgb(255,255,255)\n"
"}\n"
"\n"
"QPushButton\n"
"{\n"
"border-radius: 25px;\n"
"}\n"
"\n"
"QLineEdit\n"
"{\n"
"color:rgb(0,0,0)\n"
"}")
self.centralwidget = QtWidgets.QWidget(AutoCal)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout.setObjectName("verticalLayout")
self.groupBox = QtWidgets.QGroupBox(self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.groupBox.sizePolicy().hasHeightForWidth())
self.groupBox.setSizePolicy(sizePolicy)
self.groupBox.setAlignment(QtCore.Qt.AlignCenter)
self.groupBox.setObjectName("groupBox")
self.verticalLayout_6 = QtWidgets.QVBoxLayout(self.groupBox)
self.verticalLayout_6.setObjectName("verticalLayout_6")
self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
self.label = QtWidgets.QLabel(self.groupBox)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.label.sizePolicy().hasHeightForWidth())
self.label.setSizePolicy(sizePolicy)
self.label.setObjectName("label")
self.horizontalLayout_3.addWidget(self.label)
self.lineEdit = QtWidgets.QLineEdit(self.groupBox)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.lineEdit.sizePolicy().hasHeightForWidth())
self.lineEdit.setSizePolicy(sizePolicy)
self.lineEdit.setObjectName("lineEdit")
self.horizontalLayout_3.addWidget(self.lineEdit)
self.pushButton = QtWidgets.QPushButton(self.groupBox)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.pushButton.sizePolicy().hasHeightForWidth())
self.pushButton.setSizePolicy(sizePolicy)
self.pushButton.setObjectName("pushButton")
# self.pushButton.clicked.connect(self.openFileNameDialog )
self.horizontalLayout_3.addWidget(self.pushButton)
self.verticalLayout_6.addLayout(self.horizontalLayout_3)
self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
self.horizontalLayout_4.setObjectName("horizontalLayout_4")
self.label_2 = QtWidgets.QLabel(self.groupBox)
self.label_2.setObjectName("label_2")
self.horizontalLayout_4.addWidget(self.label_2)
self.lineEdit_2 = QtWidgets.QLineEdit(self.groupBox)
self.lineEdit_2.setText("")
self.lineEdit_2.setObjectName("lineEdit_2")
self.horizontalLayout_4.addWidget(self.lineEdit_2)
self.pushButton_2 = QtWidgets.QPushButton(self.groupBox)
self.pushButton_2.setObjectName("pushButton_2")
self.horizontalLayout_4.addWidget(self.pushButton_2)
self.verticalLayout_6.addLayout(self.horizontalLayout_4)
self.verticalLayout.addWidget(self.groupBox)
self.verticalLayout_3 = QtWidgets.QVBoxLayout()
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.groupBox_2 = QtWidgets.QGroupBox(self.centralwidget)
self.groupBox_2.setEnabled(True)
self.groupBox_2.setAlignment(QtCore.Qt.AlignCenter)
self.groupBox_2.setObjectName("groupBox_2")
self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.groupBox_2)
self.verticalLayout_5.setObjectName("verticalLayout_5")
self.scrollArea = QtWidgets.QScrollArea(self.groupBox_2)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.Ignored)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.scrollArea.sizePolicy().hasHeightForWidth())
self.scrollArea.setSizePolicy(sizePolicy)
self.scrollArea.setWidgetResizable(True)
self.scrollArea.setObjectName("scrollArea")
self.scrollAreaWidgetContents = QtWidgets.QWidget()
self.gridLayout = QtWidgets.QGridLayout(self.scrollAreaWidgetContents)
# self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 467, 331))
self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
self.scrollArea.setWidget(self.scrollAreaWidgetContents)
self.scrollArea.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.fillScrollArea()
self.verticalLayout_5.addWidget(self.scrollArea)
self.verticalLayout_3.addWidget(self.groupBox_2)
self.verticalLayout.addLayout(self.verticalLayout_3)
AutoCal.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(AutoCal)
self.menubar.setGeometry(QtCore.QRect(0, 0, 513, 22))
self.menubar.setObjectName("menubar")
self.menuWorkSpace = QtWidgets.QMenu(self.menubar)
self.menuWorkSpace.setObjectName("menuWorkSpace")
self.menuRecipients = QtWidgets.QMenu(self.menubar)
self.menuRecipients.setObjectName("menuRecipients")
AutoCal.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(AutoCal)
self.statusbar.setObjectName("statusbar")
AutoCal.setStatusBar(self.statusbar)
self.menubar.addAction(self.menuWorkSpace.menuAction())
self.menubar.addAction(self.menuRecipients.menuAction())
self.retranslateUi(AutoCal)
QtCore.QMetaObject.connectSlotsByName(AutoCal)
def retranslateUi(self, AutoCal):
_translate = QtCore.QCoreApplication.translate
AutoCal.setWindowTitle(_translate("AutoCal", "AutoCal"))
self.groupBox.setTitle(_translate("AutoCal", "Create New WorkSpace"))
self.label.setText(_translate("AutoCal", "Choose WorkSpace Directory"))
self.pushButton.setText(_translate("AutoCal", "Browse"))
self.label_2.setText(_translate("AutoCal", "WorkSpace Name"))
self.pushButton_2.setText(_translate("AutoCal", "Create"))
self.groupBox_2.setTitle(_translate("AutoCal", "Choose Existing WorkSpace"))
self.menuWorkSpace.setTitle(_translate("AutoCal", "WorkSpace"))
self.menuRecipients.setTitle(_translate("AutoCal", "Recipients"))
def fillScrollArea(self):
for i in range(50):
for j in range(50):
self.gridLayout.addWidget(QtWidgets.QPushButton("Test"), i, j)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
AutoCal = QtWidgets.QMainWindow()
ui = Ui_AutoCal()
ui.setupUi(AutoCal)
AutoCal.show()
sys.exit(app.exec_())
This produces the following scrollArea (ignore the forms):
Current Scroll Area
The main problem is that i need the buttons to always be in the visible section of the scrollArea, whereas as you can see many of them are hidden behind the scrollarea and their text is cut off. I know this is because of the positioning that my function applies to the grid layout but I'm not aware of any other way to position them. I also need the buttons to be dynamic in the sense that if horizontal space becomes greater in a higher row, the ones in the lower row will take up that space. Because of this I dont need horizontal scrolling either, which is why it's disabled.
My issue is now resolved. While flow layout was useful, it was much more intuitive to simply use QListWidget. Many thanks to both eyllanesc and musicamante for their help.
For anyone who has the same issue, the desired result can be achieved by simply creating a QlistWidget and adding items to it:
size = QSize(100,100)
self.listWidget = QListWidget()
size = QtCore.QSize(80,80)
self.listWidget.setResizeMode(QListView.Adjust)
self.listWidget.setIconSize(size)
self.listWidget.itemDoubleClicked.connect(self.itemClicked)
self.listWidget.setViewMode(QListView.IconMode)