Adding QTabWidget to a Layout Alongside Other Widgets in PyQt6

How to combine QTabWidget with other layouts without it taking over your entire window
Heads up! You've already completed this tutorial.

I'm trying to create a layout in PyQt and implement different layouts into one QHBoxLayout. Everything works fine, but when I add a QTabWidget alongside other layouts, it becomes the only visible widget — as if everything else disappears. Isn't it possible to have a QTabWidget in a layout beside other layouts?

Good news: you absolutely can place a QTabWidget inside a layout alongside other widgets and sub-layouts. You don't need to wrap it in a QGroupBox or use any special workaround. The issue usually comes down to how the tabs themselves are set up — specifically, whether the tab pages have any content and layout of their own.

Let's walk through what's happening and how to fix it.

Why the QTabWidget seems to "take over"

When you create a QTabWidget and add empty QWidget pages to it, those pages have no layout and no content. Depending on how the widget calculates its size, this can cause unexpected sizing behavior in the parent layout. The tab widget may request more space than you expect, or the other widgets may collapse because the layout gives the tab widget priority.

The fix is straightforward: make sure each tab page has a layout, and give the tab widget a reasonable size policy or stretch factor so it shares space with its neighbors.

A minimal example that works

Let's start with a small, complete example. We'll create a horizontal layout with a vertical stack of colored widgets on the left and a QTabWidget on the right — sitting happily side by side.

First, here's a simple Color helper widget that fills itself with a solid color, useful for visualizing layouts:

python
from PyQt6.QtWidgets import QWidget
from PyQt6.QtGui import QColor, QPalette


class Color(QWidget):
    """A simple widget that displays a solid color."""

    def __init__(self, color):
        super().__init__()
        self.setAutoFillBackground(True)
        palette = self.palette()
        palette.setColor(QPalette.ColorRole.Window, QColor(color))
        self.setPalette(palette)

Now let's build the full window:

python
import sys
from PyQt6.QtWidgets import (
    QApplication, QMainWindow, QWidget,
    QHBoxLayout, QVBoxLayout, QTabWidget, QLabel,
)


class Color(QWidget):
    def __init__(self, color):
        super().__init__()
        self.setAutoFillBackground(True)
        palette = self.palette()
        palette.setColor(palette.ColorRole.Window, QColor(color))
        self.setPalette(palette)


from PyQt6.QtGui import QColor, QPalette


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("QTabWidget in a Layout")

        # Main horizontal layout
        main_layout = QHBoxLayout()

        # Left side: a vertical stack of colored widgets
        left_layout = QVBoxLayout()
        left_layout.addWidget(Color("black"))
        left_layout.addWidget(Color("red"))
        left_layout.addWidget(Color("yellow"))
        main_layout.addLayout(left_layout)

        # Middle: a single green widget
        main_layout.addWidget(Color("green"))

        # Right side: a QTabWidget
        tab_widget = QTabWidget()
        tab_widget.setMovable(True)

        # Create tab pages WITH layouts and content
        tab1 = QWidget()
        tab1_layout = QVBoxLayout()
        tab1_layout.addWidget(QLabel("This is Tab 1"))
        tab1_layout.addWidget(Color("lightblue"))
        tab1.setLayout(tab1_layout)

        tab2 = QWidget()
        tab2_layout = QVBoxLayout()
        tab2_layout.addWidget(QLabel("This is Tab 2"))
        tab2_layout.addWidget(Color("lightyellow"))
        tab2.setLayout(tab2_layout)

        tab_widget.addTab(tab1, "Tab 1")
        tab_widget.addTab(tab2, "Tab 2")

        main_layout.addWidget(tab_widget)

        # Set the central widget
        container = QWidget()
        container.setLayout(main_layout)
        self.setCentralWidget(container)


app = QApplication(sys.argv)
window = MainWindow()
window.resize(800, 400)
window.show()
sys.exit(app.exec())

Run this and you'll see the colored widgets on the left, the green widget in the middle, and the tab widget on the right — all sharing the horizontal space.

What was different from the original code?

The original code created tab pages like this:

python
Tab1 = QtWidgets.QWidget()
Tab2 = QtWidgets.QWidget()
TabWidget.addTab(Tab1, "Tab1")
TabWidget.addTab(Tab2, "Tab2")

These tab pages are completely empty — no layout, no child widgets. This means Qt has very little information about how to size them, which can cause layout problems.

By giving each tab page a layout with some content, Qt can calculate proper size hints, and the tab widget behaves well alongside other items in the layout.

Controlling how much space each section gets

If you want finer control over how the horizontal space is divided, you can use stretch factors. These tell the layout how to distribute extra space among its children. For a deeper dive into how QHBoxLayout, QVBoxLayout, and QGridLayout work in PyQt6, see our guide to PyQt6 layouts.

python
main_layout.addLayout(left_layout, 1)    # stretch factor 1
main_layout.addWidget(Color("green"), 1)  # stretch factor 1
main_layout.addWidget(tab_widget, 2)      # stretch factor 2 (gets twice as much space)

The numbers are relative. Here the tab widget gets twice the space of the left section and the green widget. Adjust these to taste.

Complete working example

Here's the full example with stretch factors and a grid layout section included, similar to the original code:

python
import sys
from PyQt6.QtWidgets import (
    QApplication, QMainWindow, QWidget,
    QHBoxLayout, QVBoxLayout, QGridLayout,
    QTabWidget, QLabel,
)
from PyQt6.QtGui import QColor, QPalette


class Color(QWidget):
    """A simple widget that displays a solid color."""

    def __init__(self, color):
        super().__init__()
        self.setAutoFillBackground(True)
        palette = self.palette()
        palette.setColor(QPalette.ColorRole.Window, QColor(color))
        self.setPalette(palette)


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("QTabWidget Alongside Other Layouts")

        main_layout = QHBoxLayout()

        # Section 1: Vertical stack
        v_layout1 = QVBoxLayout()
        v_layout1.addWidget(Color("black"))
        v_layout1.addWidget(Color("red"))
        v_layout1.addWidget(Color("yellow"))
        v_layout1.setContentsMargins(0, 0, 20, 0)
        v_layout1.setSpacing(20)
        main_layout.addLayout(v_layout1, 1)

        # Section 2: Single widget
        main_layout.addWidget(Color("green"), 1)

        # Section 3: Another vertical stack
        v_layout2 = QVBoxLayout()
        v_layout2.addWidget(Color("blue"))
        v_layout2.addWidget(Color("purple"))
        main_layout.addLayout(v_layout2, 1)

        # Section 4: Grid layout
        grid_layout = QGridLayout()
        grid_layout.addWidget(Color("grey"), 0, 0)
        grid_layout.addWidget(Color("black"), 1, 0)
        grid_layout.addWidget(Color("darkgrey"), 1, 1)
        grid_layout.addWidget(Color("orange"), 2, 1)
        main_layout.addLayout(grid_layout, 1)

        # Section 5: Tab widget
        tab_widget = QTabWidget()
        tab_widget.setMovable(True)
        tab_widget.setTabPosition(QTabWidget.TabPosition.North)

        # Tab 1 with content
        tab1 = QWidget()
        tab1_layout = QVBoxLayout()
        tab1_layout.addWidget(QLabel("Content for Tab 1"))
        tab1_layout.addWidget(Color("lightblue"))
        tab1_layout.addWidget(Color("lightyellow"))
        tab1.setLayout(tab1_layout)

        # Tab 2 with content
        tab2 = QWidget()
        tab2_layout = QVBoxLayout()
        tab2_layout.addWidget(QLabel("Content for Tab 2"))
        tab2_layout.addWidget(Color("lightgreen"))
        tab2.setLayout(tab2_layout)

        tab_widget.addTab(tab1, "Tab 1")
        tab_widget.addTab(tab2, "Tab 2")

        main_layout.addWidget(tab_widget, 2)

        # Set up the central widget
        container = QWidget()
        container.setLayout(main_layout)
        self.setCentralWidget(container)


app = QApplication(sys.argv)
window = MainWindow()
window.resize(900, 400)
window.show()
sys.exit(app.exec())

When you run this, you'll see all five sections displayed side by side in a single horizontal layout — colored blocks, a grid, and a tab widget, all coexisting without any one section dominating the window.

The takeaway: QTabWidget works perfectly in any layout alongside other widgets. Just make sure the tab pages have their own layouts and content, and use stretch factors to control how space is distributed. If you'd prefer to design these complex layouts visually rather than in code, you can use Qt Designer to build your GUI layout. For a broader overview of the widgets you can place inside your tabs and layouts, take a look at our PyQt6 widgets tutorial.

Well done, you've finished this tutorial! Mark As Complete
[[ user.completed.length ]] completed [[ user.streak+1 ]] day streak

Create GUI Applications with Python & Qt6 by Martin Fitzpatrick

(PyQt6 Edition) The hands-on guide to making apps with Python — Over 15,000 copies sold!

More info Get the book

Martin Fitzpatrick

Adding QTabWidget to a Layout Alongside Other Widgets in PyQt6 was written by Martin Fitzpatrick.

Martin Fitzpatrick has been developing Python/Qt apps for 8 years. Building desktop applications to make data-analysis tools more user-friendly, Python was the obvious choice. Starting with Tk, later moving to wxWidgets and finally adopting PyQt. Martin founded PythonGUIs to provide easy to follow GUI programming tutorials to the Python community. He has written a number of popular Python books on the subject.