Skip to content

pyaccesskit.forms.layout

pyaccesskit.forms.layout

Form layout engine: turns a :class:FormSpec into exact control geometry.

The engine is pure Python — it never talks to Access — so layouts can be unit-tested and previewed. Two automatic layouts mirror Access's own control layouts:

  • stacked (single/split forms): one control per row, attached label on the left;
  • tabular (continuous/datasheet forms): labels in the form header, one row of controls in the detail.

Controls with an explicit at= keep their position; their attached label goes to their left.

MAX_FORM_EXTENT module-attribute

MAX_FORM_EXTENT = inch(22)

Access limit for form width and for each section's height.

LayoutMetrics dataclass

LayoutMetrics(
    margin: Length = (lambda: cm(0.5))(),
    label_width: Length = (lambda: cm(3.5))(),
    label_gap: Length = (lambda: cm(0.25))(),
    control_width: Length = (lambda: cm(6))(),
    row_height: Length = (lambda: cm(0.6))(),
    row_gap: Length = (lambda: cm(0.2))(),
    checkbox_size: Length = (lambda: cm(0.45))(),
    button_width: Length = (lambda: cm(3))(),
    button_height: Length = (lambda: cm(0.8))(),
    column_gap: Length = (lambda: cm(0.25))(),
    tabular_column_width: Length = (lambda: cm(3.5))(),
)

Spacing and default sizes used by the automatic layouts.

Rect dataclass

Rect(
    left: Length, top: Length, width: Length, height: Length
)

A rectangle in twips-backed lengths.

right property

right: Length

Right edge.

bottom property

bottom: Length

Bottom edge.

overlaps

overlaps(other: Rect) -> bool

Whether the two rectangles share any area.

ResolvedLabel dataclass

ResolvedLabel(
    name: str, caption: str, section: Section, rect: Rect
)

An attached label with its final geometry.

ResolvedControl dataclass

ResolvedControl(
    spec: ControlSpec,
    name: str,
    section: Section,
    rect: Rect,
    label: ResolvedLabel | None = None,
)

A control with its final name, section and geometry.

ResolvedForm dataclass

ResolvedForm(
    spec: FormSpec,
    width: Length,
    detail_height: Length,
    header_height: Length | None,
    footer_height: Length | None,
    controls: tuple[ResolvedControl, ...],
    events: tuple[EventBinding, ...],
    module_text: str | None,
)

Everything the Access materializer needs to build the form.

header_height instance-attribute

header_height: Length | None

None means the form has no header/footer sections.

has_header property

has_header: bool

Whether the form needs header/footer sections.

layout_form

layout_form(
    spec: FormSpec, metrics: LayoutMetrics = DEFAULT_METRICS
) -> ResolvedForm

Compute the geometry of every control of spec.

Raises:

Type Description
SpecError

If a control cannot be placed or the form exceeds Access's size limits.