The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Put the QTabWidget and every neighboring control in one top-level layout. Use a QHBoxLayout for a tab area beside a sidebar, a QVBoxLayout for tabs between a toolbar and status area, or nested layouts for a mixed design. Give each tab page its own layout before calling addTab(), then use stretch factors and size policies to decide which region absorbs extra space.
The tab widget is not a special full-window container. It is an ordinary widget containing a tab bar and a page area, so Qt can place it beside labels, buttons, forms, or child layouts just like any other widget.
As an Amazon Associate I earn from qualifying purchases.
The layout hierarchy that keeps QTabWidget under control
A reliable PyQt6 interface has a clear ownership tree:
- The main window or central
QWidgetowns exactly one top-level layout. - That outer layout owns the
QTabWidgetand any neighboring widgets or sub-layouts. - Each tab is backed by a separate page
QWidget. - Each page installs its own child layout before the page is passed to
addTab().
Qt’s layout system calculates positions, minimum sizes, and resizing behavior for this tree. A tab page without a layout has no organized child geometry, while a page with a layout can report sensible size requirements as its contents change. The page layout does not replace the outer layout; the two solve different problems.
#1 Best Overall
- Read Before You Buy — No Video Output: These adapters support charging and USB 2.0 data transfer, but cannot transmit video signals. Except for standard USB webcams (which use USB data only), they are not compatible with HDMI/DisplayPort cables, video-capable USB-C hubs, or docking stations with video output.
- Convert USB-A Ports to USB-C: Designed to connect USB-C earphones, cables, flash drives, card readers, and other USB-C accessories to standard USB-A ports. Plug-and-play with no drivers or software required.
- Aluminum Alloy Housing: Built with a sturdy aluminum alloy shell that aids in heat dissipation and protects against daily wear and scratches. Designed to maintain a stable and secure connection.
- Compact & Travel-Friendly: The ultra-compact design allows the adapter to stay plugged into your device without blocking adjacent ports or adding bulk, reducing wear and tear on your original USB ports.
- 12-Month Warranty: Backed by a 12-month manufacturer warranty for peace of mind. Designed to meet strict quality control standards for reliable everyday performance.
Do not create one layout for the tabs and another unrelated layout for the sidebar on the same parent widget. A widget can have one installed top-level layout. If you need several regions, create child layouts and add them to the single outer layout with addLayout().
A complete side-by-side PyQt6 example
This example places expanding tabs on the left and a compact sidebar on the right. The tab pages are created and laid out before they are inserted.
import sys
from PyQt6.QtWidgets import (
QApplication, QWidget, QTabWidget, QLabel, QPushButton,
QVBoxLayout, QHBoxLayout
)
class Window(QWidget):
def __init__(self):
super().__init__()
tabs = QTabWidget()
first_page = QWidget()
first_layout = QVBoxLayout(first_page)
first_layout.addWidget(QLabel("First tab"))
first_layout.addWidget(QPushButton("Action"))
tabs.addTab(first_page, "First")
second_page = QWidget()
second_layout = QVBoxLayout(second_page)
second_layout.addWidget(QLabel("Second tab"))
tabs.addTab(second_page, "Second")
sidebar = QVBoxLayout()
sidebar.addWidget(QLabel("Sidebar"))
sidebar.addWidget(QPushButton("Help"))
sidebar.addStretch()
outer = QHBoxLayout(self)
outer.addWidget(tabs, 1)
outer.addLayout(sidebar)
self.setWindowTitle("Tabs beside other widgets")
self.resize(800, 500)
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec())
QHBoxLayout(self) installs the one top-level layout on the window. The call outer.addWidget(tabs, 1) adds the tab widget and gives it a positive stretch factor. The sidebar is a child QVBoxLayout, so outer.addLayout(sidebar) places that complete vertical region beside the tabs.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWhen the window grows horizontally, the tab region receives the surplus space while the sidebar remains close to its preferred width. Vertically, both regions follow the outer layout’s available height; the sidebar’s addStretch() keeps its controls at the top.
Choose the outer layout by the visual relationship
Use the layout direction to express how the regions should relate. The tab widget itself does not determine whether the interface is horizontal or vertical.
| Arrangement | Outer layout | Typical children | Space-allocation pattern |
|---|---|---|---|
| Tabs beside a sidebar | QHBoxLayout |
Tab widget plus a sidebar layout or side widget | Give the tabs a positive stretch; keep the sidebar at its preferred width |
| Toolbar above tabs | QVBoxLayout |
Toolbar layout, tab widget, status area | Give the tab widget a positive vertical stretch |
| Tabs beside a stacked control panel | QHBoxLayout containing a child QVBoxLayout |
Tab widget plus a vertically arranged form or button column | Stretch the tab region; let the child column manage its own spacing |
| Two control groups beside tabs | QHBoxLayout with multiple child layouts |
Tab widget, filter layout, action layout | Assign stretch factors according to the desired proportions |
Side-by-side tabs and sidebar
The minimal pattern is:
outer = QHBoxLayout(self)
outer.addWidget(tabs, 1)
outer.addWidget(side_panel)
If the side panel contains several controls, use a child layout instead:
side_layout = QVBoxLayout()
side_layout.addWidget(QLabel("Filters"))
side_layout.addWidget(filter_edit)
side_layout.addWidget(apply_button)
side_layout.addStretch()
outer = QHBoxLayout(self)
outer.addWidget(tabs, 1)
outer.addLayout(side_layout)
addWidget() and addLayout() both add a region to the same row. The sidebar does not need a wrapper widget unless you need a background, border, independent margins, or a separate object to show and hide.
Rank #2
- 5-in-1 USB-C Hub: Experience comprehensive connectivity featuring a Power Delivery input, two USB-A 2.0 ports, a USB-A 3.0 port, and an HDMI port. (Note: The USB-C power delivery input port is only for connecting an external wall charger to power your laptop and cannot power peripheral devices.)
- 90W Pass-Through Charging: Achieve optimal charging with 90W pass-through power to your laptop, supported by a total input of 100W, with the hub reserving 10W for operational efficiency. (Note: Wall charger not included.)
- Quick Data Transfers: Accelerate your productivity with rapid data transfers using a high-speed 5Gbps USB 3.0 port and two 480Mbps USB 2.0 ports.
- 4K HDMI Display: Enhance your visual experience with a hub capable of delivering 4K resolution at 30Hz in both mirror and extend modes. Please note that this hub is compatible with MacBook (macOS 12 and newer), Windows 10 and 11, ChromeOS, and laptops equipped with DP Alt Mode and Power Delivery. Note: This device is not compatible with Linux.
- What You Get: Anker USB-C Hub (5-in-1, 4K HDMI), welcome guide, 18-month warranty, and our friendly customer service.
Toolbar, tabs, and status area stacked vertically
For a conventional editor window, stack the regions:
toolbar_layout = QHBoxLayout()
toolbar_layout.addWidget(QPushButton("New"))
toolbar_layout.addWidget(QPushButton("Open"))
toolbar_layout.addStretch()
status_layout = QHBoxLayout()
status_layout.addWidget(QLabel("Ready"))
status_layout.addStretch()
outer = QVBoxLayout(self)
outer.addLayout(toolbar_layout)
outer.addWidget(tabs, 1)
outer.addLayout(status_layout)
The positive stretch on the tab widget makes it absorb extra vertical space. The toolbar and status row retain their preferred heights.
Mixed nested layouts
Nested layouts are the normal way to build a more complex interface. A layout can contain widgets and other layouts; each child layout then controls only its own region.
left_column = QVBoxLayout()
left_column.addWidget(QLabel("Project"))
left_column.addWidget(project_tree)
left_column.addWidget(QPushButton("Refresh"))
outer = QHBoxLayout(self)
outer.addLayout(left_column)
outer.addWidget(tabs, 1)
Here the project controls form one vertical column, while the tab widget receives the remaining horizontal space.
Recommended Free Tools
Stretch factors, size policies, and minimum sizes
A stretch factor is a relative share of extra space in the layout’s direction. In outer.addWidget(tabs, 1), the tab widget has a positive factor and therefore grows when the window has room. If two regions use factors 1 and 2, the second region receives roughly twice the extra space, subject to each widget’s minimum size and size policy.
outer.addWidget(navigation, 1)
outer.addWidget(tabs, 3)
This creates a 1:3 preference for surplus horizontal space, not a guarantee that the widgets will always be exactly 25% and 75%. Minimum sizes, maximum sizes, and policies can limit the result.
Setting stretch after construction
When the tab widget is already in a box layout, you can set a stretch factor by index:
Rank #3
- Sleek 7-in-1 USB-C Hub: Features an HDMI port, two USB-A 3.0 ports, and a USB-C data port, each providing 5Gbps transfer speeds. It also includes a USB-C PD input port for charging up to 100W and dual SD and TF card slots, all in a compact design.
- Flawless 4K@60Hz Video with HDMI: Delivers exceptional clarity and smoothness with its 4K@60Hz HDMI port, making it ideal for high-definition presentations and entertainment. (Note: Only the HDMI port supports video projection; the USB-C port is for data transfer only.)
- Double Up on Efficiency: The two USB-A 3.0 ports and a USB-C port support a fast 5Gbps data rate, significantly boosting your transfer speeds and improving productivity.
- Fast and Reliable 85W Charging: Offers high-capacity, speedy charging for laptops up to 85W, so you spend less time tethered to an outlet and more time being productive.
- What You Get: Anker USB-C Hub (7-in-1), welcome guide, 18-month warranty, and our friendly customer service.
outer.addWidget(side_panel)
outer.addWidget(tabs)
outer.setStretchFactor(side_panel, 0)
outer.setStretchFactor(tabs, 1)
The index passed to setStretchFactor() is the index of the widget or layout in that box layout. Setting a positive factor on the region intended to expand is usually clearer than trying to force a fixed width on every neighbor.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →When no positive stretch is present
If all stretch factors are zero, Qt uses the participating widgets’ size policies and their size hints to distribute available space. That can be perfectly appropriate for a row of controls, but it can also make a sidebar or tab area appear unexpectedly narrow. Add a positive stretch to the region that should absorb remaining space instead of relying on implicit policy decisions.
Check the neighbor before blaming QTabWidget
A tab area can look as if it has taken over when the neighboring widget has an unusually small minimum size, a restrictive maximum size, or a policy that refuses to expand. Inspect the side region as well as the tabs. A layout can only distribute the space allowed by all of its children.
Build every tab page with its own layout
QTabWidget manages a tab bar and a page area. Each tab points to a page QWidget; the page is where you place labels, forms, tables, and buttons.
page = QWidget()
page_layout = QVBoxLayout(page)
page_layout.addWidget(QLabel("Settings"))
page_layout.addWidget(settings_form)
tabs.addTab(page, "Settings")
Passing the page to QVBoxLayout(page) installs that layout immediately. You can also create the layout separately and call page.setLayout(page_layout). The important part is that the page has a layout before it is used as a tab.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitchesWhy empty pages cause confusing sizing
An empty page has little content from which to derive a useful size hint. The resulting minimum-size calculation can be surprising, particularly when several empty pages are combined with a sidebar or other constrained controls. Give each page real content or at least an intentional layout containing the controls that will eventually appear.
If a page is deliberately empty, install its layout anyway:
Rank #4
- Dual Converters, Infinite Potential:Includes 2× USB C male to USB A female adapters and 2× USB A male to USB C female adapters. Perfect for a wide range of uses—tablets with Bluetooth keyboards, expand USB ports on macbook, and more. Two different converters for all your daily needs
- Next-Level 10Gbps & 3A Charging: No more slow 480Mbps, this usb to usb c adapter has a transfer speed of up to 10Gbps, allowing you to do more transferring in less time. This usb adapter fits both USB A and USB C charger, supporting up to 3A fast charging
- Upgraded Exquisite Craftsmanship: With an aluminum alloy housing and metal connector, the usbc to usb adapter is extremely durable and sturdy. Rigorously tested to withstand more than 10,000 times of plugging and unplugging, ensuring long-lasting performance
- Broad Compatible: The usb c to usb adapter widely supports all USB C/ USB A devices like laptops, tablets, cellphones, car chargers, and phone chargers. Such as compatible with MacBook Pro/Air 2023/2022, Thunderbolt 4/3 Devices,Apple MagSafe Watch 9/8/7/SE/Ultra, iPad Pro 2022/2021, Samsung Galaxy S23/S20/S10, and iPhone 17/16/15 Pro. Plug and play
- Please Note: To reach 10Gbps speed, keep the cable under 3.3 ft. For USB A Male to USB C adapters, try flipping the USB C connector. USB C Male to USB A adapters support bidirectional 10Gbps transfer within 3.3 ft
empty_page = QWidget()
empty_layout = QVBoxLayout(empty_page)
empty_layout.addStretch()
tabs.addTab(empty_page, "Nothing yet")
The stretch makes the page’s intent explicit and gives you a place to add content later without changing the ownership structure.
Adding pages dynamically
When a user creates a new document or workspace, construct the page, install its layout, and then insert it:
def add_workspace(self, name):
page = QWidget()
layout = QVBoxLayout(page)
layout.addWidget(QLabel(f"Workspace: {name}"))
self.tabs.addTab(page, name)
self.tabs.setCurrentWidget(page)
Build the initial tab set before calling show() whenever possible. Adding tabs after the window is visible is supported, but it can trigger layout adjustment and visible flicker while Qt recalculates the page area.
Making controls inside tabs expand correctly
The outer layout controls how much space the tab widget receives. The page layout controls how that space is shared by the page’s children. To let a table, editor, or other main control grow, place it in the page layout with an appropriate stretch position and keep small controls in non-stretch positions.
page_layout = QVBoxLayout(page)
page_layout.addWidget(QLabel("Description"))
page_layout.addWidget(description_edit, 1)
page_layout.addWidget(QPushButton("Save"))
The editor receives the page’s extra vertical space while the label and button keep their preferred heights. For a horizontal form, use a QHBoxLayout or a form layout inside the page and give the field region the expansion it needs.
Remember the two levels of stretch: the outer layout decides how much room the entire tab widget gets; the page layout decides how the widgets inside the selected page use that room. Setting a stretch only inside the page cannot make the tab widget wider if the outer row gives it no surplus space.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Diagnose the “QTabWidget takes over the whole window” symptom
When the tabs appear to occupy everything, inspect the layout tree in this order.
Best Value
- 5-in-1 Connectivity: Equipped with a 4K HDMI port, a 5 Gbps USB-C data port, two 5 Gbps USB-A ports, and a USB C 100W PD-IN port. Note: The USB C 100W PD-IN port supports only charging and does not support data transfer devices such as headphones or speakers.
- Powerful Pass-Through Charging: Supports up to 85W pass-through charging so you can power up your laptop while you use the hub. Note: Pass-through charging requires a charger (not included). Note: To achieve full power for iPad, we recommend using a 45W wall charger.
- Transfer Files in Seconds: Move files to and from your laptop at speeds of up to 5 Gbps via the USB-C and USB-A data ports. Note: The USB C 5Gbps Data port does not support video output.
- HD Display: Connect to the HDMI port to stream or mirror content to an external monitor in resolutions of up to 4K@30Hz. Note: The USB-C ports do not support video output.
- What You Get: Anker 332 USB-C Hub (5-in-1), welcome guide, our worry-free 18-month warranty, and friendly customer service.
| Symptom | Likely cause | Correction |
|---|---|---|
| Sidebar is missing or appears below the window edge | The sidebar was never added to the same top-level layout, or a second layout was created on the parent | Install one outer layout and add the sidebar with addWidget() or addLayout() |
| Tabs consume nearly all horizontal space | The tab widget has a positive stretch while the sidebar has a tiny minimum size | Check the sidebar’s size policy and minimum size; use deliberate stretch factors |
| Page controls overlap or stay in a corner | Children were placed on a page without installing a page layout | Create a page layout before adding the page to the tab widget |
| Empty tabs resize unpredictably | Pages have no content or layout from which to calculate a useful size hint | Install a page layout and add the intended controls or a stretch |
| Window flickers when tabs are added | Tabs are being constructed after the window is shown | Build the initial tabs before show(); add later pages only when needed |
| Tab contents do not grow with the window | The page layout or the outer layout gives no expanding region | Use a page-level stretch for the main control and a positive outer stretch for the tab widget |
Verify the parent has exactly one top-level layout
Look at the widget that owns the visible interface, not at the tab page. It should have one layout installed. If you need a toolbar, sidebar, or footer, represent each as a child layout or child widget in that one layout. Creating another top-level layout on the same parent can leave controls unmanaged or produce warnings.
Confirm the tab widget was added as a widget
Use outer.addWidget(tabs), not a second top-level layout around it. A QTabWidget is a QWidget, so it belongs in a layout through addWidget(). A sidebar made from a layout belongs through addLayout().
Inspect minimum and maximum constraints
Fixed widths and large minimum widths on a neighboring panel can force the tab region to consume the remainder or, at a small window size, leave no usable room for it. Remove accidental constraints or choose them intentionally. Also check that a control has not been given a maximum width that prevents it from participating in expansion.
Free tools Windows power users keep installed
One-click scans. No signup required.
Reusable patterns for common interfaces
Tabs with a fixed-width action rail
If the action rail should stay compact while the tabs expand, give the rail a sensible fixed or minimum width and the tab widget a positive stretch.
actions = QWidget()
actions_layout = QVBoxLayout(actions)
actions_layout.addWidget(QPushButton("Run"))
actions_layout.addWidget(QPushButton("Stop"))
actions_layout.addStretch()
actions.setMinimumWidth(140)
outer = QHBoxLayout(self)
outer.addWidget(tabs, 1)
outer.addWidget(actions)
Use a minimum width only when the rail genuinely needs it; otherwise its size hint and policy are less restrictive and adapt better to small windows.
Tabs between a navigation column and an inspector
navigation_layout = QVBoxLayout()
navigation_layout.addWidget(QLabel("Navigation"))
navigation_layout.addWidget(tree)
navigation_layout.addStretch()
inspector_layout = QVBoxLayout()
inspector_layout.addWidget(QLabel("Inspector"))
inspector_layout.addWidget(properties)
outer = QHBoxLayout(self)
outer.addLayout(navigation_layout)
outer.addWidget(tabs, 2)
outer.addLayout(inspector_layout, 1)
The factors express the intended relative share of surplus width: the tab region gets two parts and the inspector one. The navigation column has no positive factor, so its preferred width is preserved as far as the other constraints allow.
Tabs with a header row and footer
header = QHBoxLayout()
header.addWidget(QLabel("Project"))
header.addWidget(project_name)
header.addStretch()
footer = QHBoxLayout()
footer.addWidget(status_label)
footer.addStretch()
footer.addWidget(close_button)
outer = QVBoxLayout(self)
outer.addLayout(header)
outer.addWidget(tabs, 1)
outer.addLayout(footer)
This keeps the header and footer outside the tab pages, so they remain visible while the user switches tabs. Controls that belong only to one tab should instead be placed on that page.
A practical construction and resize checklist
- Create the main container widget and install one outer layout.
- Choose
QHBoxLayoutfor side-by-side regions orQVBoxLayoutfor stacked regions. - Create the
QTabWidgetas a child of the container. - For each tab, create a page
QWidget, install its layout, add the page controls, and calladdTab(page, label). - Create neighboring widgets or child layouts and add them to the same outer layout.
- Give the region that should absorb extra space a positive stretch factor.
- Check the neighboring widgets’ minimum sizes, maximum sizes, and size policies.
- Build the initial interface before
show(). - Resize the window from its minimum practical size to a large size and verify both the outer regions and the selected page contents.
Testing at both extremes catches different errors. A layout that looks correct at 800 by 500 can still hide a sidebar when narrowed or leave a page editor fixed at a tiny height when enlarged.
How to decide between a widget wrapper and a child layout
Add a child layout directly when you only need arrangement. Wrap the region in a QWidget when the region needs its own visual identity or lifecycle: a background palette, a frame, a context menu, independent visibility, or a named object you will replace later.
side_panel = QWidget()
side_layout = QVBoxLayout(side_panel)
side_layout.addWidget(QLabel("Tools"))
side_layout.addWidget(tool_button)
side_layout.addStretch()
outer = QHBoxLayout(self)
outer.addWidget(tabs, 1)
outer.addWidget(side_panel)
The wrapper is still just one child of the outer layout. The tab widget does not need special treatment because it is a regular widget from the outer layout’s point of view.
Quick Recap
Key principles to keep when the interface grows
- Keep the outer layout responsible for regions, not for the individual controls inside every page.
- Keep each page’s layout responsible for that page’s controls.
- Use stretch factors to express preference for extra space rather than relying on accidental defaults.
- Use nested layouts for structure; do not create competing top-level layouts on one parent.
- Treat empty pages as incomplete layout trees and give them an intentional layout.
- Construct the stable tab set before showing the window to avoid unnecessary visible rearrangement.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

