PyQt5 Layout Management Techniques
Horizontal Layout (QHBoxLayout)
QHBoxLayout arranges widgets horizontally from left to right. Key methods include:
addWidget(): Inserts widgetssetSpacing(): Controls spacing between widgets
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QPushButton
class HorizontalExample(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("Horizontal Layout Example")
hbox = QHBoxLayout()
for i in range(1, 6):
btn = QPushButton(f"Button {i}")
hbox.addWidget(btn)
hbox.setSpacing(5)
self.setLayout(hbox)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = HorizontalExample()
window.show()
sys.exit(app.exec_())
Vertical Layout (QVBoxLayout)
QVBoxLayout arranges widgets vertically from top to bottom. It shares methods with QHBoxLayout.
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton
class VerticalExample(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("Vertical Layout Example")
self.resize(200, 200)
vbox = QVBoxLayout()
for i in range(1, 6):
btn = QPushButton(f"Item {i}")
vbox.addWidget(btn)
self.setLayout(vbox)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = VerticalExample()
window.show()
sys.exit(app.exec_())
Grid Layout (QGridLayout)
QGridLayout positions widgets in a grid pattern with rows and columns.
Basic Grid Implementation
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QGridLayout, QPushButton
class GridExample(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.initUI()
def initUI(self):
grid = QGridLayout()
self.setLayout(grid)
labels = ['Clear', 'Back', None, 'Close',
'7', '8', '9', '/',
'4', '5', '6', '*',
'1', '2', '3', '-',
'0', '.', '=', '+']
positions = [(i, j) for i in range(5) for j in range(4)]
for pos, label in zip(positions, labels):
if label:
button = QPushButton(label)
grid.addWidget(button, pos[0], pos[1])
self.setWindowTitle('Grid Layout Example')
if __name__ == "__main__":
app = QApplication(sys.argv)
window = GridExample()
window.show()
sys.exit(app.exec_())
Row and Column Spanning
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QGridLayout, QLabel, QLineEdit, QTextEdit
class SpanningGrid(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.initUI()
def initUI(self):
grid = QGridLayout()
grid.setSpacing(10)
grid.addWidget(QLabel('Title:'), 0, 0)
grid.addWidget(QLineEdit(), 0, 1)
grid.addWidget(QLabel('Author:'), 1, 0)
grid.addWidget(QLineEdit(), 1, 1)
grid.addWidget(QLabel('Content:'), 2, 0)
grid.addWidget(QTextEdit(), 2, 1, 3, 1) # Span 3 rows, 1 column
self.setLayout(grid)
self.setWindowTitle('Grid Span Example')
if __name__ == "__main__":
app = QApplication(sys.argv)
window = SpanningGrid()
window.show()
sys.exit(app.exec_())
Form Layout (QFormLayout)
QFormLayout creates two-column forms with label-field pairs.
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QFormLayout, QLineEdit, QLabel
class FormExample(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("Form Layout Example")
self.resize(300, 150)
form = QFormLayout()
fields = [
("Field One:", QLineEdit()),
("Field Two:", QLineEdit()),
("Field Three:", QLineEdit())
]
for label_text, input_widget in fields:
form.addRow(QLabel(label_text), input_widget)
self.setLayout(form)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = FormExample()
window.show()
sys.exit(app.exec_())
Nested Layout Techniques
Complex interfaces combine multiple layout types.
Layouts Within Layouts
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QVBoxLayout, QGridLayout, QFormLayout, QPushButton
class NestedLayouts(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('Nested Layout Example')
main_layout = QHBoxLayout()
# Create different layout types
h_layout = QHBoxLayout()
v_layout = QVBoxLayout()
grid_layout = QGridLayout()
form_layout = QFormLayout()
# Add widgets to layouts
h_layout.addWidget(QPushButton("H1"))
h_layout.addWidget(QPushButton("H2"))
v_layout.addWidget(QPushButton("V1"))
v_layout.addWidget(QPushButton("V2"))
grid_layout.addWidget(QPushButton("G1"), 0, 0)
grid_layout.addWidget(QPushButton("G2"), 0, 1)
form_layout.addRow(QLabel("Label:"), QLineEdit())
# Create container widgets
h_container = QWidget()
v_container = QWidget()
g_container = QWidget()
f_container = QWidget()
h_container.setLayout(h_layout)
v_container.setLayout(v_layout)
g_container.setLayout(grid_layout)
f_container.setLayout(form_layout)
# Add containers to main layout
main_layout.addWidget(h_container)
main_layout.addWidget(v_container)
main_layout.addWidget(g_container)
main_layout.addWidget(f_container)
self.setLayout(main_layout)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = NestedLayouts()
window.show()
sys.exit(app.exec_())
QSplitter Dynamic Layout
QSplitter provdies resizable sections with drag handles.
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QSplitter, QFrame, QTextEdit
from PyQt5.QtCore import Qt
class SplitterExample(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
hbox = QHBoxLayout(self)
self.setWindowTitle('QSplitter Example')
self.setGeometry(300, 300, 450, 300)
top_frame = QFrame()
top_frame.setFrameShape(QFrame.StyledPanel)
bottom_frame = QFrame()
bottom_frame.setFrameShape(QFrame.StyledPanel)
horizontal_split = QSplitter(Qt.Horizontal)
editor = QTextEdit()
horizontal_split.addWidget(top_frame)
horizontal_split.addWidget(editor)
horizontal_split.setSizes([150, 250])
vertical_split = QSplitter(Qt.Vertical)
vertical_split.addWidget(horizontal_split)
vertical_split.addWidget(bottom_frame)
hbox.addWidget(vertical_split)
self.setLayout(hbox)
if __name__ == '__main__':
app = QApplication(sys.argv)
demo = SplitterExample()
demo.show()
sys.exit(app.exec_())