Recently in a Python webinar, someone asked me a question on arranging widgets. After researching various methods, I explained them QGridLayout in PyQt6 . In this tutorial, I will explain how to arrange widgets using QGridLayout in PyQt6 along with suitable examples and screenshots.
QGridLayout in PyQt6
QGridLayout is a layout manager that arranges widgets in a grid pattern of rows and columns. Unlike simpler layouts like QVBoxLayout or QHBoxLayout, QGridLayout gives you precise control over widget positioning by allowing you to specify exact coordinates for each element.
Read How to Create QPushButton Widget in PyQt6?
Key Advantages of QGridLayout:
- Two-dimensional arrangement – position widgets by row and column coordinates
- Cell spanning – widgets can span multiple rows or columns
- Alignment control – adjust how widgets align within their cells
- Responsive design – grid cells automatically resize with the window
- Precise positioning – allows for complex layouts without nested layout managers
Method 1: Basic QGridLayout Implementation
Let’s start with a simple implementation to understand the core concepts:
import sys
from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget,
QGridLayout, QPushButton, QLabel)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Basic QGridLayout Example")
self.setGeometry(100, 100, 400, 300)
# Create central widget and grid layout
central_widget = QWidget()
grid_layout = QGridLayout(central_widget)
# Add widgets to specific grid positions (row, column)
grid_layout.addWidget(QLabel("Name:"), 0, 0)
grid_layout.addWidget(QLabel("John Smith"), 0, 1)
grid_layout.addWidget(QLabel("Email:"), 1, 0)
grid_layout.addWidget(QLabel("john.smith@example.com"), 1, 1)
grid_layout.addWidget(QPushButton("Save"), 2, 0)
grid_layout.addWidget(QPushButton("Cancel"), 2, 1)
self.setCentralWidget(central_widget)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())You can see the output in the screenshot below

In this basic example, I’ve created a simple form layout using QGridLayout with three rows and two columns. The key method to note is addWidget(), which takes three parameters:
- The widget to add
- The row position (starting from 0)
- The column position (starting from 0)
This allows us to create a clean, aligned form without the need for nested layouts.
Check out How to Create QLabel Widget in PyQt6?
Method 2: Span Rows and Columns
One of the most efficient features of QGridLayout is the ability to have widgets span multiple rows or columns. This is perfect for creating complex forms and dashboards:
import sys
from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget,
QGridLayout, QPushButton, QLabel,
QLineEdit, QTextEdit)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Spanning Rows and Columns")
self.setGeometry(100, 100, 500, 400)
central_widget = QWidget()
grid_layout = QGridLayout(central_widget)
# Title spanning two columns
title = QLabel("Boston Customer Registration Form")
title.setStyleSheet("font-size: 16pt; font-weight: bold;")
grid_layout.addWidget(title, 0, 0, 1, 2) # row, col, rowspan, colspan
# Form fields
grid_layout.addWidget(QLabel("First Name:"), 1, 0)
grid_layout.addWidget(QLineEdit(), 1, 1)
grid_layout.addWidget(QLabel("Last Name:"), 2, 0)
grid_layout.addWidget(QLineEdit(), 2, 1)
grid_layout.addWidget(QLabel("Comments:"), 3, 0)
# Text edit spanning 2 rows
comments = QTextEdit()
grid_layout.addWidget(comments, 3, 1, 2, 1) # spans 2 rows
# Button row
grid_layout.addWidget(QPushButton("Submit"), 5, 0)
grid_layout.addWidget(QPushButton("Clear Form"), 5, 1)
self.setCentralWidget(central_widget)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())You can see the output in the screenshot below

In this example, I’ve expanded the addWidget() method to use two additional parameters:
- The row span (how many rows the widget occupies)
- The column span (how many columns the widget occupies)
The title spans two columns (colspan=2), and the comments text area spans two rows (rowspan=2). This technique gives you tremendous flexibility in designing complex layouts.
Method 3: Control Spacing and Alignment
For professional-looking UIs, controlling the spacing and alignment within a grid is essential:
import sys
from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget,
QGridLayout, QPushButton, QLabel,
QLineEdit)
from PyQt6.QtCore import Qt
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Spacing and Alignment in QGridLayout")
self.setGeometry(100, 100, 500, 300)
central_widget = QWidget()
grid_layout = QGridLayout(central_widget)
# Set spacing for the entire grid
grid_layout.setSpacing(15) # 15 pixels between cells
# Set margins for the layout (left, top, right, bottom)
grid_layout.setContentsMargins(20, 20, 20, 20)
# Add widgets with different alignments
label1 = QLabel("Username:")
grid_layout.addWidget(label1, 0, 0, alignment=Qt.AlignmentFlag.AlignRight)
grid_layout.addWidget(QLineEdit(), 0, 1)
label2 = QLabel("Password:")
grid_layout.addWidget(label2, 1, 0, alignment=Qt.AlignmentFlag.AlignRight)
grid_layout.addWidget(QLineEdit(), 1, 1)
# Add buttons with different alignments
save_btn = QPushButton("Chicago Login")
grid_layout.addWidget(save_btn, 2, 0, 1, 2,
alignment=Qt.AlignmentFlag.AlignCenter)
self.setCentralWidget(central_widget)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())You can see the output in the screenshot below

In this example, I’ve introduced several important spacing and alignment techniques:
setSpacing(pixels): Controls the gap between cells in the gridsetContentsMargins(left, top, right, bottom): Sets padding around the entire layout- The optional
alignmentparameter: Controls how widgets align within their cells
These methods allow for fine-tuned control over the visual appearance of your UI, making it both functionally and aesthetically pleasing.
Check out How to Create Icons for Windows in PyQt6?
Method 4: Create a Complex Dashboard Layout
When building real-world applications, especially admin panels, dashboards, or data-driven interfaces, you often need to combine multiple layouts — such as horizontal, vertical, and grid layouts — into one complex structure.
import sys
from PyQt6.QtWidgets import (
QApplication, QWidget, QVBoxLayout, QHBoxLayout,
QLabel, QPushButton, QListWidget, QTextEdit
)
class DashboardWindow(QWidget):
def __init__(self):
super().__init__()
self.init_ui()
def init_ui(self):
# -------- Main Layout (Vertical) --------
main_layout = QVBoxLayout()
# -------- Header --------
header = QLabel("📊 Dashboard")
header.setStyleSheet("font-size: 24px; font-weight: bold; padding: 10px;")
main_layout.addWidget(header)
# -------- Content Layout (Horizontal) --------
content_layout = QHBoxLayout()
# Sidebar (List of navigation options)
sidebar = QListWidget()
sidebar.addItems(["Overview", "Reports", "Settings"])
sidebar.setMaximumWidth(150)
content_layout.addWidget(sidebar)
# Main Content Area (TextEdit to represent dynamic content)
self.content_area = QTextEdit()
self.content_area.setPlaceholderText("Main content goes here...")
content_layout.addWidget(self.content_area)
# Add content layout to main layout
main_layout.addLayout(content_layout)
# -------- Footer --------
footer = QPushButton("Logout")
footer.setStyleSheet("margin: 10px;")
main_layout.addWidget(footer)
# Set main layout
self.setLayout(main_layout)
self.setWindowTitle("Complex Dashboard Layout")
self.setGeometry(100, 100, 600, 400)
# Run the app
if __name__ == '__main__':
app = QApplication(sys.argv)
window = DashboardWindow()
window.show()
sys.exit(app.exec())Nesting Layouts show how vertical and horizontal layouts can work together.
Read Types of Windows in PyQt6
Conclusion
In this tutorial, I explained how to arrange widgets using QGridLayout in PyQt6. I discussed four important methods to achieve this task such as basic QGridLayout implementation, span rows and columns, control spacing and alignment, and creating a complex dashboard layout.
You may read:
- How to Use QVBoxLayout in PyQt6 for Vertical Layouts?
- How to Use QHBoxLayout in PyQt6 for Horizontal Layouts?
- How to Create QLineEdit Widget in PyQt6?

I am Bijay Kumar, a Microsoft MVP in SharePoint. Apart from SharePoint, I started working on Python, Machine learning, and artificial intelligence for the last 5 years. During this time I got expertise in various Python libraries also like Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… for various clients in the United States, Canada, the United Kingdom, Australia, New Zealand, etc. Check out my profile.