After years of developing desktop applications, I’ve found that understanding vertical layouts is essential for creating professional-looking GUIs. QVBoxLayout is one of PyQt6’s most efficient layout classes, designed specifically for arranging widgets in a vertical column. In this article, I will explain how to use QVBoxLayout in PyQt6 for vertical layouts along with examples and screenshots.
QVBoxLayout in PyQt6
QVBoxLayout is a layout manager that arranges widgets one above the other linearly. When you add a widget to QVBoxLayout, it’s appended to the bottom of the column, creating a natural top-to-bottom flow.
Read How to Create QLabel Widget in PyQt6?
Key Features of QVBoxLayout
- Vertical Arrangement: Automatically stacks widgets vertically
- Responsive Design: Adjusts to window resizing
- Layout Integration: Can be nested within other layouts
- Margin Control: Customizable spacing between widgets and borders
- Stretch Factors: Allows for proportional space distribution
Set Up Your Development Environment
Before getting into QVBoxLayout, let’s ensure you have the necessary tools installed:
# Install PyQt6 using pip
pip install PyQt6Now, let’s import the required modules for our examples:
import sys
from PyQt6.QtWidgets import (
QApplication, QMainWindow, QWidget,
QVBoxLayout, QPushButton, QLabel
)Check out Basic Widgets in PyQt6
Method 1: Basic QVBoxLayout Implementation
The simplest way to use QVBoxLayout is to create an instance and add widgets to it sequentially. Here’s a basic example:
import sys
from PyQt6.QtWidgets import (
QApplication, QMainWindow, QWidget,
QVBoxLayout, QPushButton, QLabel
)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Basic QVBoxLayout Example")
self.setGeometry(100, 100, 400, 300)
# Create a central widget to hold our layout
central_widget = QWidget()
self.setCentralWidget(central_widget)
# Create vertical layout
layout = QVBoxLayout()
central_widget.setLayout(layout)
# Add widgets to layout
layout.addWidget(QLabel("Welcome to my PyQt6 Application"))
layout.addWidget(QPushButton("New York"))
layout.addWidget(QPushButton("Los Angeles"))
layout.addWidget(QPushButton("Chicago"))
layout.addWidget(QPushButton("Houston"))
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 created a simple window with a label and four buttons arranged vertically. The buttons will be stacked one above the other in the order they were added to the layout.
Read How to Create Icons for Windows in PyQt6?
Method 2: Control Spacing and Margins
One of the key aspects of creating polished UIs is managing the space between elements. QVBoxLayout provides several methods to control spacing:
import sys
from PyQt6.QtWidgets import (
QApplication, QMainWindow, QWidget,
QVBoxLayout, QPushButton, QLabel
)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("QVBoxLayout with Custom Spacing")
self.setGeometry(100, 100, 400, 300)
central_widget = QWidget()
self.setCentralWidget(central_widget)
# Create vertical layout with custom spacing
layout = QVBoxLayout()
# Set spacing between widgets (in pixels)
layout.setSpacing(20)
# Set margins (left, top, right, bottom)
layout.setContentsMargins(30, 10, 30, 10)
central_widget.setLayout(layout)
# Add widgets to layout
layout.addWidget(QLabel("Enter your details:"))
layout.addWidget(QPushButton("First Name"))
layout.addWidget(QPushButton("Last Name"))
layout.addWidget(QPushButton("Email"))
layout.addWidget(QPushButton("Phone"))
layout.addWidget(QPushButton("Submit"))
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())You can see the output in the screenshot below.

Here, I’ve set a spacing of 20 pixels between each widget and added content margins to create padding around the entire layout. This approach creates a cleaner, more professional look with appropriate breathing room between elements.
Check out Types of Windows in PyQt6
Method 3: Use Stretch Factors for Flexible Layouts
Stretch factors in PyQt6 help control how much space each widget gets when the window resizes. By assigning different stretch values to widgets in a QVBoxLayout, you can specify relative proportions for each widget.
import sys
from PyQt6.QtWidgets import (
QApplication, QMainWindow, QWidget,
QVBoxLayout, QPushButton, QLabel
)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("QVBoxLayout with Stretch Factors")
self.setGeometry(100, 100, 400, 400)
central_widget = QWidget()
self.setCentralWidget(central_widget)
layout = QVBoxLayout()
central_widget.setLayout(layout)
# Header section
layout.addWidget(QLabel("Application Dashboard"))
# Add stretch factor to push content apart
layout.addStretch(1)
# Main content section
layout.addWidget(QPushButton("San Francisco"))
layout.addWidget(QPushButton("Austin"))
layout.addWidget(QPushButton("Seattle"))
# Add another stretch factor (twice as strong)
layout.addStretch(2)
# Footer section
layout.addWidget(QPushButton("Settings"))
layout.addWidget(QPushButton("Logout"))
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 created a more sophisticated layout with three distinct sections: a header, main content, and footer. The addStretch() method adds flexible space that expands as the window resizes, with the numeric parameter determining the relative strength of the stretch.
Read How to Install PyQt6 on Different Platforms?
Method 4: Nested Layouts for Complex Interfaces
For more complex interfaces, you’ll often need to combine different types of layouts. QVBoxLayout works seamlessly with other layout types:
import sys
from PyQt6.QtWidgets import (
QApplication, QMainWindow, QWidget, QFrame,
QVBoxLayout, QHBoxLayout, QPushButton, QLabel
)
from PyQt6.QtCore import Qt
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Nested Layouts Example")
self.setGeometry(100, 100, 500, 400)
central_widget = QWidget()
self.setCentralWidget(central_widget)
# Main vertical layout
main_layout = QVBoxLayout(central_widget)
# Header with horizontal layout
header_frame = QFrame()
header_frame.setFrameShape(QFrame.Shape.Box)
header_layout = QHBoxLayout(header_frame)
header_layout.addWidget(QLabel("Denver Dashboard"))
header_layout.addStretch(1)
header_layout.addWidget(QPushButton("Help"))
header_layout.addWidget(QPushButton("Account"))
main_layout.addWidget(header_frame)
# Content section (vertical)
content_layout = QVBoxLayout()
content_layout.addWidget(QLabel("Main Content Area"))
# Row of buttons (horizontal)
button_layout = QHBoxLayout()
button_layout.addWidget(QPushButton("Option 1"))
button_layout.addWidget(QPushButton("Option 2"))
button_layout.addWidget(QPushButton("Option 3"))
content_layout.addLayout(button_layout)
content_layout.addWidget(QPushButton("More Information"))
main_layout.addLayout(content_layout)
# Footer
footer_frame = QFrame()
footer_frame.setFrameShape(QFrame.Shape.Box)
footer_layout = QHBoxLayout(footer_frame)
footer_layout.addWidget(QLabel("© 2025 My Application"))
footer_layout.addStretch(1)
footer_layout.addWidget(QPushButton("Privacy"))
footer_layout.addWidget(QPushButton("Terms"))
main_layout.addWidget(footer_frame)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())This example demonstrates a common application layout with a header, content area, and footer. I’ve nested horizontal layouts within the main vertical layout to create a more complex UI structure.
Check out Create a Basic Window in PyQt6
Method 5: Use. addLayout() to Combine Layouts
Another efficient technique is to create separate layout instances and add them to your main QVBoxLayout:
import sys
from PyQt6.QtWidgets import (
QApplication, QMainWindow, QWidget,
QVBoxLayout, QHBoxLayout, QGridLayout,
QPushButton, QLabel, QLineEdit
)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Combined Layouts Example")
self.setGeometry(100, 100, 500, 400)
central_widget = QWidget()
self.setCentralWidget(central_widget)
# Main vertical layout
main_layout = QVBoxLayout(central_widget)
# Title section
main_layout.addWidget(QLabel("Miami Inventory System"))
# Form layout (created as a grid)
form_layout = QGridLayout()
form_layout.addWidget(QLabel("Product ID:"), 0, 0)
form_layout.addWidget(QLineEdit(), 0, 1)
form_layout.addWidget(QLabel("Product Name:"), 1, 0)
form_layout.addWidget(QLineEdit(), 1, 1)
form_layout.addWidget(QLabel("Quantity:"), 2, 0)
form_layout.addWidget(QLineEdit(), 2, 1)
# Add the form layout to the main layout
main_layout.addLayout(form_layout)
# Button row
button_layout = QHBoxLayout()
button_layout.addWidget(QPushButton("Save"))
button_layout.addWidget(QPushButton("Clear"))
button_layout.addWidget(QPushButton("Cancel"))
# Add the button layout to the main layout
main_layout.addLayout(button_layout)
# Add stretch to push everything up
main_layout.addStretch(1)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())This example demonstrates how to build a clean and structured GUI using nested layouts in PyQt6. By combining QVBoxLayout, QGridLayout, and QHBoxLayout, you achieve modular design.
Conclusion
Int is tutorial, I explained how to use QVBoxLayout in PyQt6 for vertical layouts. I discussed five important methods to accomplish this task, such as using basic QVBoxLayout implementation, control spacing and margins, stretch factors for flexible layouts, nested layouts for complex interfaces, and use. addLayout() to combine layouts.
You may like to read:
- How to Use QHBoxLayout in PyQt6 for Horizontal Layouts?
- How to Create QLineEdit Widget in PyQt6?
- How to Create QPushButton 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.