Skip to content

TabWidget

Qt Base Class: QTabWidget

Signature: QTabWidget(self, parent: Optional[PySide6.QtWidgets.QWidget] = None) -> None

Base classes

Name Children Inherits
WidgetMixin
prettyqt.widgets.widget
QTabWidget
PySide6.QtWidgets
QTabWidget(self, parent: Optional[PySide6.QtWidgets.QWidget] \= None) -> None

⋔ Inheritance diagram

graph TD
  1473296226608["widgets.TabWidget"]
  1473293688240["widgets.WidgetMixin"]
  1473299815024["core.ObjectMixin"]
  140713234304496["builtins.object"]
  1473245548480["gui.PaintDeviceMixin"]
  1473290864320["QtWidgets.QTabWidget"]
  1473290849680["QtWidgets.QWidget"]
  1473288842240["QtCore.QObject"]
  1473291690208["Shiboken.Object"]
  1473300082368["QtGui.QPaintDevice"]
  1473293688240 --> 1473296226608
  1473299815024 --> 1473293688240
  140713234304496 --> 1473299815024
  1473245548480 --> 1473293688240
  140713234304496 --> 1473245548480
  1473290864320 --> 1473296226608
  1473290849680 --> 1473290864320
  1473288842240 --> 1473290849680
  1473291690208 --> 1473288842240
  140713234304496 --> 1473291690208
  1473300082368 --> 1473290849680
  1473291690208 --> 1473300082368

🛈 DocStrings

Bases: WidgetMixin, QTabWidget

Stack of tabbed widgets.

Source code in prettyqt\widgets\tabwidget.py
class TabWidget(widgets.WidgetMixin, widgets.QTabWidget):
    """Stack of tabbed widgets."""

    def __init__(
        self, closable: bool = False, detachable: bool = False, **kwargs
    ) -> None:
        # Basic initalization
        super().__init__(**kwargs)
        self.animator = animations.Animator(self)
        self.tabCloseRequested.connect(self.remove_tab)
        self.tab_bar = widgets.TabBar(self)

        self.setTabBar(self.tab_bar)

        # Used to keep a reference to detached tabs since their QMainWindow
        # does not have a parent
        self.detached_tabs: dict[str, DetachedTab] = {}
        if detachable:
            self.set_detachable()
        self.set_closable(closable)

    def __len__(self) -> int:
        return self.count()

    @overload
    def __getitem__(self, index: int) -> widgets.QWidget:
        ...

    @overload
    def __getitem__(self, index: slice) -> listdelegators.ListDelegator[widgets.QWidget]:
        ...

    def __getitem__(
        self, index: int | slice
    ) -> widgets.QWidget | listdelegators.ListDelegator[widgets.QWidget]:
        match index:
            case int():
                if index >= self.count():
                    raise IndexError(index)
                return self.widget(index)
            case slice():
                rng = range(index.start or 0, index.stop or self.count(), index.step or 1)
                return listdelegators.ListDelegator(self.widget(i) for i in rng)
            case _:
                raise TypeError(index)

    def __contains__(self, item: widgets.QWidget):
        return self.indexOf(item) >= 0

    def update_tab_bar_visibility(self):
        """Update visibility of the tabBar depending of the number of tabs.

        0 or 1 tab -> tabBar hidden, 2+ tabs - >tabBar visible
        need to be called explicitly, or be connected to tabInserted/tabRemoved
        """
        self.tabBar().setVisible(self.count() > 1)

    def set_icon_size(self, size: datatypes.SizeType):
        """Set size of the icons."""
        self.setIconSize(datatypes.to_size(size))

    def set_document_mode(self, state: bool = True) -> None:
        self.setDocumentMode(state)

    def set_tab_shape(self, shape: TabShapeStr | widgets.QTabWidget.TabShape):
        """Set tab shape for the tabwidget.

        Args:
            shape: tab shape to use
        """
        self.setTabShape(TAB_SHAPES.get_enum_value(shape))

    def get_tab_shape(self) -> TabShapeStr:
        """Return tab shape.

        Returns:
            tab shape
        """
        return TAB_SHAPES.inverse[self.tabShape()]

    def set_tab_position(self, position: TabPositionStr | widgets.QTabWidget.TabPosition):
        """Set tab position for the tabwidget.

        Args:
            position: tab position to use
        """
        self.setTabPosition(TAB_POSITION.get_enum_value(position))

    def get_tab_position(self) -> TabPositionStr:
        """Return tab position.

        Returns:
            tab position
        """
        return TAB_POSITION.inverse[self.tabPosition()]

    def get_children(self) -> list[tuple]:
        return [
            (
                self.widget(i),
                self.tabText(i),
                self.tab_icon(i),
                self.tabToolTip(i),
                self.tabWhatsThis(i),
            )
            for i in range(self.count())
        ]

    def tab_icon(self, i: int) -> gui.Icon | None:
        icon = self.tabIcon(i)
        return None if icon.isNull() else gui.Icon(icon)

    def set_detachable(self):
        self.tab_bar.tab_doubleclicked.connect(self.detach_tab)
        core.CoreApplication.call_on_exit(self.close_detached_tabs)
        self.setMovable(True)

    def set_closable(self, closable: bool = True):
        self.setTabsClosable(closable)

    @core.Slot(int, core.QPoint)
    def detach_tab(self, index: int, point: datatypes.PointType):
        """Detach tab by removing its contents and placing them in a DetachedTab window.

        Args:
            index (int): index location of the tab to be detached
            point (core.QPoint): screen pos for creating the new DetachedTab window

        """
        # Get the tab content
        name = self.tabText(index)
        icon = self.tab_icon(index) or self.window().windowIcon()
        widget = self.widget(index)

        try:
            widget_rect = widget.frameGeometry()
        except AttributeError:
            return

        # Create a new detached tab window
        detached_tab = DetachedTab(name, widget)
        detached_tab.set_modality("none")
        detached_tab.set_icon(icon)
        detached_tab.setGeometry(widget_rect)
        detached_tab.on_close.connect(self.attach_tab)
        detached_tab.move(datatypes.to_point(point))
        detached_tab.show()

        # Create a reference to maintain access to the detached tab
        self.detached_tabs[name] = detached_tab

    def add(self, widget: widgets.QWidget | widgets.QLayout):
        """Add widget / layout to TabWidget.

        Tab label is chosen based on following order:
        windowTitle -> objectName -> className
        """
        label = (widget.windowTitle() if isinstance(widget, widgets.QWidget) else "") or (
            widget.objectName() or type(widget).__name__
        )
        self.add_tab(widget, label)

    def add_tab(
        self,
        item: widgets.QWidget | widgets.QLayout,
        label: str,
        icon: datatypes.IconType = None,
        position: int | None = None,
        show: bool = False,
    ) -> int:
        if isinstance(item, widgets.QLayout):
            widget = widgets.Widget()
            widget.set_layout(item)
        else:
            widget = item
        if position is None:
            position = len(self)
        if not icon:
            index = self.insertTab(position, widget, label)
        else:
            icon = iconprovider.get_icon(icon)
            index = self.insertTab(position, widget, icon, label)
        if show:
            self.setCurrentIndex(index)
        return index

    def attach_tab(
        self,
        widget: widgets.QWidget | widgets.QLayout,
        name: str,
        icon: datatypes.IconType = None,
        insert_at: int | None = None,
    ):
        """Re-attach tab.

        Re-attach the tab by removing the content from the DetachedTab window,
        closing it, and placing the content back into the DetachableTabWidget.

        Args:
            widget (Union[widgets.QWidget, widgets.QLayout]): the content widget
                from the DetachedTab window
            name (str): the name of the detached tab
            icon (datatypes.IconType, optional): the window icon for the detached tab
            insert_at (Optional[int], optional): insert the re-attached tab at the
                given index
        """
        widget.setParent(self)

        # Remove the reference
        del self.detached_tabs[name]

        # Determine if the given image and the main window icon are the same.
        # If they are, then do not add the icon to the tab
        self.add_tab(widget, name, icon=icon, position=insert_at, show=True)

    def close_detached_tabs(self):
        """Close all tabs that are currently detached."""
        tabs = list(self.detached_tabs.values())
        for tab in tabs:
            tab.close()

    @core.Slot(int)
    def remove_tab(self, index_or_widget: int | widgets.QWidget):
        index = (
            self.indexOf(index_or_widget)
            if isinstance(index_or_widget, widgets.QWidget)
            else index_or_widget
        )
        widget = (
            self.widget(index_or_widget)
            if isinstance(index_or_widget, int)
            else index_or_widget
        )
        self.removeTab(index)
        if widget is not None:
            widget.deleteLater()

    @core.Slot(widgets.QWidget, str)
    def open_widget(self, widget: widgets.QWidget, title: str = "Unnamed"):
        """Create a tab containing delivered widget."""
        self.add_tab(widget, title, icon="mdi.widgets", show=True)

    def set_tab(self, index: int, position: str, widget: widgets.QWidget | None = None):
        self.tabBar().set_tab(index, position, widget)

    def create_tab_preview(self, index: int, width: int = 200) -> widgets.Label:
        widget = widgets.Label(self)
        widget.setScaledContents(True)
        px = self.widget(index).grab().scaledToWidth(width)
        widget.setPixmap(px)
        widget.resize(width, width)
        return widget

add(widget: widgets.QWidget | widgets.QLayout)

Add widget / layout to TabWidget.

Tab label is chosen based on following order: windowTitle -> objectName -> className

Source code in prettyqt\widgets\tabwidget.py
def add(self, widget: widgets.QWidget | widgets.QLayout):
    """Add widget / layout to TabWidget.

    Tab label is chosen based on following order:
    windowTitle -> objectName -> className
    """
    label = (widget.windowTitle() if isinstance(widget, widgets.QWidget) else "") or (
        widget.objectName() or type(widget).__name__
    )
    self.add_tab(widget, label)

attach_tab(widget: widgets.QWidget | widgets.QLayout, name: str, icon: datatypes.IconType = None, insert_at: int | None = None)

Re-attach tab.

Re-attach the tab by removing the content from the DetachedTab window, closing it, and placing the content back into the DetachableTabWidget.

Parameters:

Name Type Description Default
widget Union[QWidget, QLayout]

the content widget from the DetachedTab window

required
name str

the name of the detached tab

required
icon IconType

the window icon for the detached tab

None
insert_at Optional[int]

insert the re-attached tab at the given index

None
Source code in prettyqt\widgets\tabwidget.py
def attach_tab(
    self,
    widget: widgets.QWidget | widgets.QLayout,
    name: str,
    icon: datatypes.IconType = None,
    insert_at: int | None = None,
):
    """Re-attach tab.

    Re-attach the tab by removing the content from the DetachedTab window,
    closing it, and placing the content back into the DetachableTabWidget.

    Args:
        widget (Union[widgets.QWidget, widgets.QLayout]): the content widget
            from the DetachedTab window
        name (str): the name of the detached tab
        icon (datatypes.IconType, optional): the window icon for the detached tab
        insert_at (Optional[int], optional): insert the re-attached tab at the
            given index
    """
    widget.setParent(self)

    # Remove the reference
    del self.detached_tabs[name]

    # Determine if the given image and the main window icon are the same.
    # If they are, then do not add the icon to the tab
    self.add_tab(widget, name, icon=icon, position=insert_at, show=True)

close_detached_tabs()

Close all tabs that are currently detached.

Source code in prettyqt\widgets\tabwidget.py
def close_detached_tabs(self):
    """Close all tabs that are currently detached."""
    tabs = list(self.detached_tabs.values())
    for tab in tabs:
        tab.close()

detach_tab(index: int, point: datatypes.PointType)

Detach tab by removing its contents and placing them in a DetachedTab window.

Parameters:

Name Type Description Default
index int

index location of the tab to be detached

required
point QPoint

screen pos for creating the new DetachedTab window

required
Source code in prettyqt\widgets\tabwidget.py
@core.Slot(int, core.QPoint)
def detach_tab(self, index: int, point: datatypes.PointType):
    """Detach tab by removing its contents and placing them in a DetachedTab window.

    Args:
        index (int): index location of the tab to be detached
        point (core.QPoint): screen pos for creating the new DetachedTab window

    """
    # Get the tab content
    name = self.tabText(index)
    icon = self.tab_icon(index) or self.window().windowIcon()
    widget = self.widget(index)

    try:
        widget_rect = widget.frameGeometry()
    except AttributeError:
        return

    # Create a new detached tab window
    detached_tab = DetachedTab(name, widget)
    detached_tab.set_modality("none")
    detached_tab.set_icon(icon)
    detached_tab.setGeometry(widget_rect)
    detached_tab.on_close.connect(self.attach_tab)
    detached_tab.move(datatypes.to_point(point))
    detached_tab.show()

    # Create a reference to maintain access to the detached tab
    self.detached_tabs[name] = detached_tab

get_tab_position() -> TabPositionStr

Return tab position.

Source code in prettyqt\widgets\tabwidget.py
def get_tab_position(self) -> TabPositionStr:
    """Return tab position.

    Returns:
        tab position
    """
    return TAB_POSITION.inverse[self.tabPosition()]

get_tab_shape() -> TabShapeStr

Return tab shape.

Source code in prettyqt\widgets\tabwidget.py
def get_tab_shape(self) -> TabShapeStr:
    """Return tab shape.

    Returns:
        tab shape
    """
    return TAB_SHAPES.inverse[self.tabShape()]

open_widget(widget: widgets.QWidget, title: str = 'Unnamed')

Create a tab containing delivered widget.

Source code in prettyqt\widgets\tabwidget.py
@core.Slot(widgets.QWidget, str)
def open_widget(self, widget: widgets.QWidget, title: str = "Unnamed"):
    """Create a tab containing delivered widget."""
    self.add_tab(widget, title, icon="mdi.widgets", show=True)

set_icon_size(size: datatypes.SizeType)

Set size of the icons.

Source code in prettyqt\widgets\tabwidget.py
def set_icon_size(self, size: datatypes.SizeType):
    """Set size of the icons."""
    self.setIconSize(datatypes.to_size(size))

set_tab_position(position: TabPositionStr | widgets.QTabWidget.TabPosition)

Set tab position for the tabwidget.

Parameters:

Name Type Description Default
position TabPositionStr | TabPosition

tab position to use

required
Source code in prettyqt\widgets\tabwidget.py
def set_tab_position(self, position: TabPositionStr | widgets.QTabWidget.TabPosition):
    """Set tab position for the tabwidget.

    Args:
        position: tab position to use
    """
    self.setTabPosition(TAB_POSITION.get_enum_value(position))

set_tab_shape(shape: TabShapeStr | widgets.QTabWidget.TabShape)

Set tab shape for the tabwidget.

Parameters:

Name Type Description Default
shape TabShapeStr | TabShape

tab shape to use

required
Source code in prettyqt\widgets\tabwidget.py
def set_tab_shape(self, shape: TabShapeStr | widgets.QTabWidget.TabShape):
    """Set tab shape for the tabwidget.

    Args:
        shape: tab shape to use
    """
    self.setTabShape(TAB_SHAPES.get_enum_value(shape))

update_tab_bar_visibility()

Update visibility of the tabBar depending of the number of tabs.

0 or 1 tab -> tabBar hidden, 2+ tabs - >tabBar visible need to be called explicitly, or be connected to tabInserted/tabRemoved

Source code in prettyqt\widgets\tabwidget.py
def update_tab_bar_visibility(self):
    """Update visibility of the tabBar depending of the number of tabs.

    0 or 1 tab -> tabBar hidden, 2+ tabs - >tabBar visible
    need to be called explicitly, or be connected to tabInserted/tabRemoved
    """
    self.tabBar().setVisible(self.count() > 1)

⌗ Property table

Qt Property Type Doc
objectName QString
modal bool
windowModality Qt::WindowModality
enabled bool
geometry QRect
frameGeometry QRect
normalGeometry QRect
x int
y int
pos QPoint
frameSize QSize
size QSize
width int
height int
rect QRect
childrenRect QRect
childrenRegion QRegion
sizePolicy QSizePolicy
minimumSize QSize
maximumSize QSize
minimumWidth int
minimumHeight int
maximumWidth int
maximumHeight int
sizeIncrement QSize
baseSize QSize
palette QPalette
font QFont
cursor QCursor
mouseTracking bool
tabletTracking bool
isActiveWindow bool
focusPolicy Qt::FocusPolicy
focus bool
contextMenuPolicy Qt::ContextMenuPolicy
updatesEnabled bool
visible bool
minimized bool
maximized bool
fullScreen bool
sizeHint QSize
minimumSizeHint QSize
acceptDrops bool
windowTitle QString
windowIcon QIcon
windowIconText QString
windowOpacity double
windowModified bool
toolTip QString
toolTipDuration int
statusTip QString
whatsThis QString
accessibleName QString
accessibleDescription QString
layoutDirection Qt::LayoutDirection
autoFillBackground bool
styleSheet QString
locale QLocale
windowFilePath QString
inputMethodHints QFlags
tabPosition QTabWidget::TabPosition
tabShape QTabWidget::TabShape
currentIndex int
count int
iconSize QSize
elideMode Qt::TextElideMode
usesScrollButtons bool
documentMode bool
tabsClosable bool
movable bool
tabBarAutoHide bool