I want to dynamically create QWidgets and dynamically arrange them in a QGridLayout

I’m coding a project management app for my school project. In this app, the user creates a “folder” to organize their different projects. I have implemented this functionality in the “create new project” button. Ideally, when the user creates their first project, the project should appear as a white square in the top left corner of the grid. When the user creates their second project, the next white square should take the position (0,1) and so on. I want only four project folders (white squares) per row. After that, new projects will be added to the second row, and so on. After three rows, the area should become scrollable.

I’m having trouble achieving this behavior. Currently, when I add the first project to position (0,0), the white square appears in the center of the grid. When I add the second white square, the space gets divided between the two squares. This continues until there are four squares in the row. The second row works as expected, but when the third row is created, all the white squares merge together and no scroll bar appears.

This is what happens when I create the first project
When I add the second project

After the fourth project has been added everything works as expected until the 9th project is created (first white square in the third row. This is when thew white squares merge.
third row of projects

This is how it should look like when I add the first project

This is how all rows should look like:

Below is my code:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>from PyQt6.QtWidgets import QGridLayout, QHBoxLayout, QWidget, QVBoxLayout, QLineEdit, QPushButton, QApplication, QMainWindow, QSizePolicy, QScrollArea, QSpacerItem
from PyQt6.QtGui import QIcon, QAction
from PyQt6.QtCore import Qt
from ColorWidget import Color #QWidget with a background Color
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
# Window Properties
self.setWindowTitle('project')
self.setMinimumSize(1050, 650)
# Main Layout)
main_pannel = Color('grey')
main_pannel_layout = QVBoxLayout()
main_pannel_layout.setContentsMargins(50,100,50,0)
main_pannel_layout.setSpacing(20)
#Main Pannel Sub frames
# Control
control_frame = Color('grey') #QWidget with background color Grey
control_layout = QHBoxLayout()
control_layout.setContentsMargins(0,0,0,0)
# Project
project_frame = Color('grey') #QWidget with background color Grey
self.project_layout = QGridLayout()
self.project_layout.setContentsMargins(0, 50, 0, 50)
self.project_layout.setHorizontalSpacing(20)
self.project_layout.setVerticalSpacing(20)
#Scroll Area
scroll_area = QScrollArea()
scroll_area.setWidgetResizable(True)
scroll_area.setWidget(project_frame)
#Control Widgets
#create new project button
create_project_button = QPushButton(parent = control_frame, text = 'new project')
create_project_button.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
create_project_button.clicked.connect(self.create_project)
control_layout.addWidget(create_project_button)
#set Layout for Control Frame
control_frame.setLayout(control_layout)
# Project Widgets
self.project_count = 0
#Set layout for Project Framself.
project_frame.setLayout(self.project_layout)
#Add subframes to Main Pannel
main_pannel_layout.addWidget(control_frame)
main_pannel_layout.addWidget(project_frame,1)
main_pannel.setLayout(main_pannel_layout)
# Set up main widget
canvas = QWidget()
canvas.setLayout(main_pannel_layout)
self.setCentralWidget(canvas)
def create_project(self):
row = self.project_count // 4
col = self.project_count % 4
new_project = Color('white')
new_project.setFixedSize(200, 150) # Set a fixed size for each project widget
self.project_layout.addWidget(new_project, row, col)
self.project_count += 1
if __name__ == '__main__':
app = QApplication([])
with open('BunkerWindowStyleSheet.css', 'r') as f:
app.setStyleSheet(f.read())
window = MainWindow()
window.show()
app.exec()
</code>
<code>from PyQt6.QtWidgets import QGridLayout, QHBoxLayout, QWidget, QVBoxLayout, QLineEdit, QPushButton, QApplication, QMainWindow, QSizePolicy, QScrollArea, QSpacerItem from PyQt6.QtGui import QIcon, QAction from PyQt6.QtCore import Qt from ColorWidget import Color #QWidget with a background Color class MainWindow(QMainWindow): def __init__(self): super().__init__() # Window Properties self.setWindowTitle('project') self.setMinimumSize(1050, 650) # Main Layout) main_pannel = Color('grey') main_pannel_layout = QVBoxLayout() main_pannel_layout.setContentsMargins(50,100,50,0) main_pannel_layout.setSpacing(20) #Main Pannel Sub frames # Control control_frame = Color('grey') #QWidget with background color Grey control_layout = QHBoxLayout() control_layout.setContentsMargins(0,0,0,0) # Project project_frame = Color('grey') #QWidget with background color Grey self.project_layout = QGridLayout() self.project_layout.setContentsMargins(0, 50, 0, 50) self.project_layout.setHorizontalSpacing(20) self.project_layout.setVerticalSpacing(20) #Scroll Area scroll_area = QScrollArea() scroll_area.setWidgetResizable(True) scroll_area.setWidget(project_frame) #Control Widgets #create new project button create_project_button = QPushButton(parent = control_frame, text = 'new project') create_project_button.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed) create_project_button.clicked.connect(self.create_project) control_layout.addWidget(create_project_button) #set Layout for Control Frame control_frame.setLayout(control_layout) # Project Widgets self.project_count = 0 #Set layout for Project Framself. project_frame.setLayout(self.project_layout) #Add subframes to Main Pannel main_pannel_layout.addWidget(control_frame) main_pannel_layout.addWidget(project_frame,1) main_pannel.setLayout(main_pannel_layout) # Set up main widget canvas = QWidget() canvas.setLayout(main_pannel_layout) self.setCentralWidget(canvas) def create_project(self): row = self.project_count // 4 col = self.project_count % 4 new_project = Color('white') new_project.setFixedSize(200, 150) # Set a fixed size for each project widget self.project_layout.addWidget(new_project, row, col) self.project_count += 1 if __name__ == '__main__': app = QApplication([]) with open('BunkerWindowStyleSheet.css', 'r') as f: app.setStyleSheet(f.read()) window = MainWindow() window.show() app.exec() </code>
from PyQt6.QtWidgets import QGridLayout, QHBoxLayout, QWidget, QVBoxLayout, QLineEdit, QPushButton, QApplication, QMainWindow, QSizePolicy, QScrollArea, QSpacerItem
from PyQt6.QtGui import QIcon, QAction
from PyQt6.QtCore import Qt
from ColorWidget import Color #QWidget with a background Color


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

    # Window Properties
        self.setWindowTitle('project')
        self.setMinimumSize(1050, 650)


    # Main Layout)
        main_pannel = Color('grey')
        main_pannel_layout = QVBoxLayout()
        main_pannel_layout.setContentsMargins(50,100,50,0)
        main_pannel_layout.setSpacing(20)


    #Main Pannel Sub frames

        # Control 
        control_frame = Color('grey') #QWidget with background color Grey
        control_layout = QHBoxLayout()
        control_layout.setContentsMargins(0,0,0,0)
    

        # Project
        project_frame = Color('grey') #QWidget with background color Grey
        self.project_layout = QGridLayout()
        self.project_layout.setContentsMargins(0, 50, 0, 50)
        self.project_layout.setHorizontalSpacing(20)
        self.project_layout.setVerticalSpacing(20)

            #Scroll Area 
        scroll_area = QScrollArea()
        scroll_area.setWidgetResizable(True)
        scroll_area.setWidget(project_frame)
        

        #Control Widgets

        #create new project button
        create_project_button = QPushButton(parent = control_frame, text = 'new project')
        create_project_button.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
        create_project_button.clicked.connect(self.create_project)

        
        control_layout.addWidget(create_project_button)
        
        #set Layout for Control Frame
        control_frame.setLayout(control_layout)
        

        # Project Widgets
        self.project_count = 0
          
        
        #Set layout for Project Framself.
        project_frame.setLayout(self.project_layout)

       
    #Add subframes to Main Pannel 
        main_pannel_layout.addWidget(control_frame)
        main_pannel_layout.addWidget(project_frame,1)
        main_pannel.setLayout(main_pannel_layout)


        
    # Set up main widget
        canvas = QWidget()
        canvas.setLayout(main_pannel_layout)
        self.setCentralWidget(canvas)

    def create_project(self):
        row = self.project_count // 4
        col = self.project_count % 4
        new_project = Color('white')
        new_project.setFixedSize(200, 150)  # Set a fixed size for each project widget
        self.project_layout.addWidget(new_project, row, col)
        self.project_count += 1

 

if __name__ == '__main__':
    app = QApplication([])
    with open('BunkerWindowStyleSheet.css', 'r') as f:
        app.setStyleSheet(f.read())
    window = MainWindow()
    window.show()
    app.exec()

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật