Agent skill

wxpython-specialist

Stars 217
Forks 22

Install this agent skill to your Project

npx add-skill https://github.com/Community-Access/accessibility-agents/tree/main/.gemini/extensions/a11y-agents/skills/wxpython-specialist

SKILL.md

wxPython Specialist

wxPython GUI expert covering sizer layouts, event handling, AUI framework, custom controls, threading (wx.CallAfter/wx.PostEvent), dialog design, menu/toolbar construction, and desktop accessibility (screen readers, keyboard navigation). Covers cross-platform gotchas for Windows and macOS.

Core Principles

  1. Sizers, always. Never use absolute positioning.
  2. Events, not polling. Bind events properly.
  3. Thread safety is non-negotiable. Use wx.CallAfter() or wx.PostEvent() from worker threads.
  4. Accessibility is built in. Every control must be keyboard-accessible with proper names.
  5. Cross-platform by default. Know the Windows/macOS differences.

Sizer Layouts

  • wx.BoxSizer(wx.VERTICAL/wx.HORIZONTAL) for stack or row layouts
  • wx.GridBagSizer(vgap, hgap) for form layouts
  • wx.SizerFlags(proportion).Expand().Border(wx.ALL, border) modern API
  • Proportion: 0 = minimum size, 1+ = takes remaining space
  • wx.EXPAND fills the non-main axis
  • Always call self.SetSizerAndFit(sizer)

Event Handling

  • self.Bind(wx.EVT_BUTTON, self.handler, self.btn) standard binding
  • wx.lib.newevent.NewEvent() for custom event types
  • wx.PostEvent(target, evt) for thread-safe event posting
  • event.Skip() to let other handlers also process the event
  • Always handle wx.EVT_CLOSE for cleanup

Screen Reader Key Event Pitfalls

Screen readers like NVDA and JAWS install a low-level keyboard hook (WH_KEYBOARD_LL) that intercepts every keystroke system-wide before any window message reaches the application. When the screen reader consumes a key (e.g., Enter on a focused wx.ListBox), the WM_KEYDOWN message never arrives -- so EVT_KEY_DOWN and EVT_CHAR handlers silently fail.

Why EVT_CHAR_HOOK works: Even when WM_KEYDOWN does arrive, native Win32 controls (ListBox, TreeView, ListView) may process the message in their own WndProc before wxPython generates EVT_KEY_DOWN. EVT_CHAR_HOOK fires at the top-level window within wxWidgets' own event processing, before the native control handler runs.

Event priority order:

  1. EVT_CHAR_HOOK -- fires first, before native control processing
  2. EVT_KEY_DOWN -- may never fire if control consumes the message
  3. EVT_CHAR -- may never fire
  4. EVT_KEY_UP -- fires on key release

Correct pattern:

python
class MyFrame(wx.Frame):
    def __init__(self, parent):
        super().__init__(parent, title="Example")
        self.list_box = wx.ListBox(self, choices=["Item 1", "Item 2"])

        # WRONG -- silently fails when NVDA/JAWS is active
        # self.list_box.Bind(wx.EVT_KEY_DOWN, self.on_key)

        # CORRECT -- fires before the native control handler
        self.Bind(wx.EVT_CHAR_HOOK, self.on_char_hook)

    def on_char_hook(self, event):
        key = event.GetKeyCode()
        focused = wx.Window.FindFocus()
        if focused == self.list_box and key == wx.WXK_RETURN:
            self.activate_selected_item()
            return  # consume the key
        if key == wx.WXK_ESCAPE:
            self.Close()
            return
        event.Skip()  # let other keys propagate

Prefer semantic events when available:

Widget Semantic Event Use Instead Of
wx.ListCtrl EVT_LIST_ITEM_ACTIVATED EVT_KEY_DOWN for Enter
wx.TreeCtrl EVT_TREE_ITEM_ACTIVATED EVT_KEY_DOWN for Enter
wx.Button EVT_BUTTON EVT_KEY_DOWN for Enter/Space
wx.CheckBox EVT_CHECKBOX EVT_KEY_DOWN for Space

Semantic events fire regardless of activation method (keyboard, mouse, or assistive technology), making them inherently screen-reader-safe.

wx.ListBox does not provide EVT_LISTBOX_ACTIVATED in most wxPython versions. Use EVT_CHAR_HOOK for ListBox, or migrate to wx.ListCtrl.

Desktop Accessibility

How screen readers get labels from wxPython controls:

  • Inputs and other controls: NVDA/VoiceOver read the preceding wx.StaticText as the label. Add a wx.StaticText immediately before the control in the sizer -- sizer/HWND sibling order determines the association.
  • Buttons: The label= constructor parameter is already the accessible name. No extra work needed.
  • Bitmap buttons and image-only controls: Use SetToolTip() to provide descriptive text. For a programmatic accessible name, subclass wx.Accessible.

Common Mistake to Avoid: wx.Window.SetName() sets an internal widget name used by FindWindowByName() for programmatic widget lookup. It has no effect on screen readers. NVDA, VoiceOver, and JAWS do not read SetName() values as accessible labels.

python
# CORRECT -- StaticText immediately before the control in the sizer
label = wx.StaticText(panel, label="Username:")
ctrl = wx.TextCtrl(panel)
sizer.Add(label, 0, wx.ALL, 5)
sizer.Add(ctrl, 0, wx.EXPAND | wx.ALL, 5)

# CORRECT -- button label= is already the accessible name
btn = wx.Button(panel, label="Save document")

# WRONG -- SetName() does NOT make controls accessible to screen readers
ctrl.SetName("Username")  # Only affects FindWindowByName() -- screen readers ignore it
  • Tab order follows sizer order -- use MoveAfterInTabOrder() to override
  • wx.AcceleratorTable for keyboard shortcuts
  • CreateStdDialogButtonSizer() auto-handles platform button order
  • Color alone must never convey state -- add text or icons
  • All actions must be reachable by keyboard
  • Key handlers on list/tree controls must use EVT_CHAR_HOOK (not EVT_KEY_DOWN/EVT_CHAR)

Accessibility Detection Rules

ID Severity What to Flag
WX-A11Y-001 Critical Control without a preceding wx.StaticText label (inputs/selects) and without a label= parameter (buttons)
WX-A11Y-002 Critical Window with no wx.AcceleratorTable
WX-A11Y-003 Critical Mouse event without equivalent keyboard event
WX-A11Y-004 Serious Dialog without CreateStdDialogButtonSizer() or Escape handling
WX-A11Y-005 Serious ShowModal() without SetFocus() on a meaningful control
WX-A11Y-006 Serious Bitmap/BitmapButton without SetToolTip() or wx.Accessible subclass
WX-A11Y-007 Moderate Color as sole state indicator
WX-A11Y-008 Moderate Status change without accessible announcement
WX-A11Y-009 Moderate Custom-drawn panel without wx.Accessible subclass
WX-A11Y-010 Minor Tab order mismatches visual reading order
WX-A11Y-011 Serious Virtual list/tree without meaningful GetItemText override
WX-A11Y-012 Moderate Menu item without accelerator key
WX-A11Y-013 Critical EVT_KEY_DOWN/EVT_CHAR on ListBox/ListCtrl/TreeCtrl/DataViewCtrl for Enter/Space/Escape -- use EVT_CHAR_HOOK or semantic events
WX-A11Y-014 Serious wx.ListCtrl with EVT_KEY_DOWN for Enter instead of EVT_LIST_ITEM_ACTIVATED

Cross-Platform

Area Windows macOS
Menu bar Window title bar Global top bar
Button order OK / Cancel Cancel / OK (auto)
DPI Per-monitor aware Retina auto

Cross-Team Routing

Need Route To
Python language / packaging / testing python-specialist
Platform a11y APIs (UIA, MSAA, NSAccessibility) desktop-a11y-specialist
Screen reader testing (NVDA, JAWS) desktop-a11y-testing-coach
Build a11y scanner / rule engine a11y-tool-builder
Web accessibility audit web-accessibility-wizard
Document accessibility audit document-accessibility-wizard

Expand your agent's capabilities with these related and highly-rated skills.

Community-Access/accessibility-agents

i18n-accessibility

Internationalization and RTL accessibility specialist. Audits dir attributes, BCP 47 lang tags, bidirectional text handling, mixed-direction forms, icon mirroring in RTL, and inline language switches. Ensures multilingual and RTL content is accessible to assistive technologies.

217 22
Explore
Community-Access/accessibility-agents

testing-coach

Accessibility testing coach for web applications. Use when you need guidance on HOW to test accessibility - screen reader testing with NVDA/VoiceOver/JAWS, keyboard testing workflows, automated testing setup (axe-core, Playwright, Pa11y), browser DevTools accessibility features, and creating accessibility test plans. Does not write product code - teaches and guides testing practices.

217 22
Explore
Community-Access/accessibility-agents

pdf-scan-config

Internal helper agent. Invoked by orchestrator agents via Task tool. PDF accessibility scan configuration manager. Use to create, edit, validate, or explain .a11y-pdf-config.json files that control which PDF accessibility rules are enabled or disabled. Manages three rule layers (PDFUA conformance, PDFBP best practices, PDFQ pipeline), severity filters, and preset profiles.

217 22
Explore
Community-Access/accessibility-agents

aria-specialist

ARIA implementation specialist for web applications. Use when building or reviewing any interactive web component including modals, tabs, accordions, comboboxes, live regions, carousels, custom widgets, forms, or dynamic content. Also use when reviewing ARIA usage for correctness. Applies to any web framework or vanilla HTML/CSS/JS.

217 22
Explore
Community-Access/accessibility-agents

Desktop A11y Testing Coach

Desktop accessibility testing expert -- NVDA, JAWS, Narrator, VoiceOver screen readers, Accessibility Insights for Windows, automated UIA testing, keyboard-only testing, high contrast verification.

217 22
Explore
Community-Access/accessibility-agents

lighthouse-bridge

Internal helper agent. Invoked by orchestrator agents via Task tool. Internal helper that bridges Lighthouse CI accessibility audit data with the agent ecosystem. Parses Lighthouse reports, normalizes accessibility findings, tracks score regressions, and deduplicates against local scans.

217 22
Explore

Didn't find tool you were looking for?

Be as detailed as possible for better results