PyQt QHBoxLayout

Summary: in this tutorial, you’ll learn how to use the PyQt QHBoxLayout to arrange widgets horizontally.

PyQt layout defines the way to arrange child widgets on a parent widget. PyQt supports a variety of layout classes, each has a layout strategy that suits a particular situation.

The steps for using a layout class are as follows:

  • First, create a layout object from a layout class.
  • Second, assign the layout object to the parent widget’s layout property using the setLayout() method.
  • Third, add widgets to the layout using the addWidget() method of the layout object.

Also, you can add layouts to a layout using the addLayout() method. This allows you to create a more complex layout for arranging widgets.

Introduction to the PyQt QHBoxLayout

The QHBoxLayout divides the parent widget into horizontal boxes and places the child widgets sequentially from left to right.

The following program shows how to use the QHBoxLayout:

import sys
from PyQt6.QtWidgets import QApplication, QWidget, QPushButton, QHBoxLayout


class MainWindow(QWidget):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.setWindowTitle('PyQt QHBoxLayout')

        # create a layout
        layout = QHBoxLayout()
        self.setLayout(layout)

        # create buttons and add them to the layout
        titles = ['Yes', 'No', 'Cancel']
        buttons = [QPushButton(title) for title in titles]
        for button in buttons:
            layout.addWidget(button)

        # show the window
        self.show()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    sys.exit(app.exec())Code language: Python (python)

Output:

PyQt QHBoxLayout

How it works.

First, create a QHBoxLayout object:

layout = QHBoxLayout()Code language: Python (python)

Second, set the layout for the MainWindow by calling its setLayout() method:

self.setLayout(layout)Code language: Python (python)

Third, create three buttons using QPushButton and add them to the layout using the addWidget() method:

titles = ['Yes', 'No', 'Cancel']
buttons = [QPushButton(title) for title in titles]
for button in buttons:
    layout.addWidget(button)Code language: Python (python)

Note that we use a list comprehension to create three push buttons based on the list of titles.

Alignments

When the parent widget has more space for child widgets, the child widgets will stretch horizontally like this:

PyQt QHBoxLayout - Buttons Stretch Horizontally

To keep the child widgets at their default sizes and align them horizontally, you use a horizontal spacer.

Align left

To align the button to the left of the parent widget, you add a horizontal spacer after the child widgets to the QHBoxLayout. For example:

PyQt QHBoxLayout - Align Left using a horizontal spacer

In this example, the horizontal spacer with stretch to the end of the layout and left enough space for the buttons.

To add a horizontal spacer to the end of the layout, you call the addStretch() method after adding all buttons to the layout:

import sys
from PyQt6.QtWidgets import QApplication, QWidget, QPushButton, QHBoxLayout


class MainWindow(QWidget):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.setWindowTitle('PyQt QHBoxLayout')

        # create a layout
        layout = QHBoxLayout()
        self.setLayout(layout)

        # create buttons and add them to the layout
        titles = ['Yes', 'No', 'Cancel']
        buttons = [QPushButton(title) for title in titles]
        for button in buttons:
            layout.addWidget(button)

        # add a spacer
        layout.addStretch()

        # show the window
        self.show()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    sys.exit(app.exec())

Code language: Python (python)

Align right

Similarly, you can add a spacer at the beginning of the layout to push the buttons to the right:

PyQt QHBoxLayout - Align Right using a horizontal spacer

To do this, you call the addStretch() method before adding buttons to the layout:

import sys
from PyQt6.QtWidgets import QApplication, QWidget, QPushButton, QHBoxLayout


class MainWindow(QWidget):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.setWindowTitle('PyQt QHBoxLayout')

        # create a layout
        layout = QHBoxLayout()
        self.setLayout(layout)

        # add a spacer
        layout.addStretch()

        # create buttons and add them to the layout
        titles = ['Yes', 'No', 'Cancel']
        buttons = [QPushButton(title) for title in titles]
        for button in buttons:
            layout.addWidget(button)

        # show the window
        self.show()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    sys.exit(app.exec())

Code language: Python (python)

Align center

To align buttons to the center, you add one horizontal spacer at the beginning and the other at the end of the layout:

To do that you call addStretch() method before and after adding buttons to the layout:

import sys
from PyQt6.QtWidgets import QApplication, QWidget, QPushButton, QHBoxLayout


class MainWindow(QWidget):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.setWindowTitle('PyQt QHBoxLayout')

        # create a layout
        layout = QHBoxLayout()
        self.setLayout(layout)

        # add a spacer
        layout.addStretch()

        # create buttons and add them to the layout
        titles = ['Yes', 'No', 'Cancel']
        buttons = [QPushButton(title) for title in titles]
        for button in buttons:
            layout.addWidget(button)

        # add a spacer
        layout.addStretch()

        # show the window
        self.show()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    sys.exit(app.exec())
Code language: Python (python)

Placing a horizontal spacer between widgets

It’s possible to place the horizontal spacer between widgets to push them to the left and right of the layout:

import sys
from PyQt6.QtWidgets import QApplication, QWidget, QPushButton, QHBoxLayout


class MainWindow(QWidget):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.setWindowTitle('PyQt QHBoxLayout')

        # create a layout
        layout = QHBoxLayout()
        self.setLayout(layout)

        # create buttons and add them to the layout
        titles = ['Yes', 'No', 'Cancel']
        buttons = [QPushButton(title) for title in titles]

        # add the buttons
        layout.addWidget(buttons[0])
        layout.addWidget(buttons[1])
        
        # add a spacer
        layout.addStretch()

        # add the cancel button
        layout.addWidget(buttons[2])

        # show the window
        self.show()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    sys.exit(app.exec())

Code language: Python (python)

Setting layout stretch factors

By default, a child widget takes its default size. To set the space that the child widget can stretch, you call the setStretchFactor() method of the QHBoxLayout object:

setStretchFactor(widget, factor)

For example, we can make the Yes and No buttons the same size and take twice as much space as the Cancel button using the stretch factors:

PyQt QHBoxLayout - Layout Stretch Factors
import sys
from PyQt6.QtWidgets import QApplication, QWidget, QPushButton, QHBoxLayout


class MainWindow(QWidget):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.setWindowTitle('PyQt QHBoxLayout')

        # create a layout
        layout = QHBoxLayout()
        self.setLayout(layout)

        # create buttons and add them to the layout
        titles = ['Yes', 'No', 'Cancel']
        buttons = [QPushButton(title) for title in titles]
        for button in buttons:
            layout.addWidget(button)

        # set the stretch factors
        layout.setStretchFactor(buttons[0], 2)
        layout.setStretchFactor(buttons[1], 2)
        layout.setStretchFactor(buttons[2], 1)

        # show the window
        self.show()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    sys.exit(app.exec())
Code language: Python (python)

Setting spaces between widgets

By default, the QHBoxLayout sets a default space between the child widgets. To change the spaces between them, you use the setSpacing() method of the QHBoxLayout object.

The following example uses the setSpacing() method to set the spaces between buttons to 50px:

PyQt QHBoxLayout - Spacing
import sys
from PyQt6.QtWidgets import QApplication, QWidget, QPushButton, QHBoxLayout


class MainWindow(QWidget):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.setWindowTitle('PyQt QHBoxLayout')

        # create a layout
        layout = QHBoxLayout()
        self.setLayout(layout)

        # create buttons and add them to the layout
        titles = ['Yes', 'No', 'Cancel']
        buttons = [QPushButton(title) for title in titles]
        for button in buttons:
            layout.addWidget(button)

        layout.setSpacing(50)

        # show the window
        self.show()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    sys.exit(app.exec())
Code language: Python (python)

Setting content margins

By default, the QHBoxLayout sets specific left, top, right, and bottom margins for child widgets. To change the margins, you use the setContentsMargins() method:

PyQt QHBoxLayout - Setting Contents Margins Example
setContentsMargins(self, left: int, top: int, right: int, bottom: int) -> NoneCode language: PHP (php)

The following example uses the setContentsMargins() to set the left, top, right, and bottom margins for the child widgets:

import sys
from PyQt6.QtWidgets import QApplication, QWidget, QPushButton, QHBoxLayout


class MainWindow(QWidget):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.setWindowTitle('PyQt QHBoxLayout')

        # create a layout
        layout = QHBoxLayout()
        self.setLayout(layout)

        # create buttons and add them to the layout
        titles = ['Yes', 'No', 'Cancel']
        buttons = [QPushButton(title) for title in titles]
        for button in buttons:
            layout.addWidget(button)

        layout.setContentsMargins(50, 50, 50, 50)

        # show the window
        self.show()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    sys.exit(app.exec())
Code language: Python (python)

Summary

  • Use QHBoxLayout to divide the parent widget into horizontal boxes and place them sequentially from left to right.
  • Use the addStretch() method of the QHBoxLayout object to add a horizontal spacer to the layout to align the child widgets left, right, or center.
  • Use the setStretchFactor() method of the QHBoxLayout object to set the stretch factor for a child widget.
  • Use the setSpacing() method of the QHBoxLayout object to set the spaces between child widgets.
  • Use the setContentsMargins() method of the QHBoxLayout object to set the left, top, right, and bottom margins.
Did you find this tutorial helpful ?