Skip to content

visualdynamics.gui.drawer_tab

drawer_tab

The handle drawn on the edge of a collapsible drawer.

The handle is a flat tab with rounded shoulders and feet that flare out into the edge it sits on, with the word in the middle and a chevron on each side pointing the way a click will move the edge. icons/drawer-tab-shape.svg is the reference drawing. It has one fixed width, so the shape is drawn here from its radii at whatever width the label needs, and the colors come from the palette so it works in the light and dark themes.

It is painted by hand instead of styled, because a stylesheet can only draw a box, and the flared feet are what make it look like a handle on an edge instead of a button near one.

Classes:

Name Description
DrawerTab

A checkable handle for a drawer on the bottom edge; checked means

Classes

DrawerTab

DrawerTab(text: str, parent: QWidget | None = None)

Bases: QAbstractButton

A checkable handle for a drawer on the bottom edge; checked means open. Only the bottom edge is drawn for now. A drawer on another edge would need the shape and the text turned, and drawer_glyph already turns the chevron for any edge.

Methods:

Name Description
outline

The tab's outline at its current size, left open along the

Source code in src/visualdynamics/gui/drawer_tab.py
def __init__(self, text: str, parent: QWidget | None = None) -> None:
    super().__init__(parent)
    self.setCheckable(True)
    self.setText(text)
    self.setAttribute(Qt.WidgetAttribute.WA_Hover)
    # The tab floats over the 3-D view, and the VTK widget takes a
    # native window (`winId()`), which makes every sibling up the
    # tree native too — this one included, and it has to be, or it
    # could never draw over the view. A native child has a surface
    # of its own, and it needs an alpha channel or everything
    # outside the flared outline shows as a gray box on the black
    # scene (Brandon, 2026-09-04). Declared translucent here, before
    # the surface exists, so it is made with one. Not enough on its
    # own — see `paintEvent` for the rest of that story.
    self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
Methods:
outline
outline() -> QPainterPath

The tab's outline at its current size, left open along the base so no line is drawn across the edge it sits on.

Source code in src/visualdynamics/gui/drawer_tab.py
def outline(self) -> QPainterPath:
    """The tab's outline at its current size, left open along the
    base so no line is drawn across the edge it sits on."""
    w, h = self.width(), self.height()
    top, base = self.TOP, h - 0.5
    foot, shoulder = self.FOOT, self.SHOULDER
    path = QPainterPath(QPointF(0, base))
    # a concave foot: a quarter circle centered on the edge, from
    # straight below its center round to its right
    path.arcTo(QRectF(-foot, base - 2 * foot, 2 * foot, 2 * foot),
               270, 90)
    path.lineTo(foot, top + shoulder)
    path.arcTo(QRectF(foot, top, 2 * shoulder, 2 * shoulder), 180, -90)
    path.lineTo(w - foot - shoulder, top)
    path.arcTo(QRectF(w - foot - 2 * shoulder, top,
                      2 * shoulder, 2 * shoulder), 90, -90)
    path.lineTo(w - foot, base - foot)
    path.arcTo(QRectF(w - foot, base - 2 * foot, 2 * foot, 2 * foot),
               180, 90)
    return path

Functions: