From ui-review
Render a PySide6/PyQt screen to an image and improve it by LOOKING at it, not by reading source. Use when asked to review, critique, fix, tighten, or polish a desktop GUI's layout — settings panels, dialogs, wizard steps, dock panels — or whenever you just edited Qt UI code and want to verify how it actually renders. Provides an offscreen screenshot harness (no running app, no display needed) and a render -> view -> critique -> fix -> re-render loop. Critiques against the ui-design-standards skill. Also supports live, interactive review via qt-mcp when the app is running and instrumented.
How this skill is triggered — by the user, by Claude, or both
Slash command
/ui-review:ui-visual-reviewThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
A coding agent can't fix what it can't see. Qt layout reads fine in source and
A coding agent can't fix what it can't see. Qt layout reads fine in source and still renders with dead space, clipped labels, full-width inputs, or buttons shoved off-screen. The only reliable way to catch that is to render the screen to an image and look at it. This skill is that loop.
scripts/snap.py). No
running app and no display are required — see references/pyside.md.sizeHint);ui-design-standards. Name each violation as
rule-ID + widget + concrete fix.Never declare a UI "fixed" without a fresh screenshot proving it.
import os
os.environ["QT_QPA_PLATFORM"] = "offscreen" # MUST be set before importing Qt
# ... build the widget, apply the real theme ...
widget.grab().save("shot.png") # render to an image, no window
widget.grab() paints the widget into a pixmap with no visible window and no
GPU. It works in CI and in a headless agent run. Standard widgets and
QGraphicsView render fully offscreen; QOpenGLWidget / live matplotlib GL
content needs a real display (use qt-mcp live mode for those — see below).
scripts/snap.py. Best for iterating on layout:
deterministic, scriptable, needs no running app. This is what you'll use 90%
of the time. Details + recipes: references/pyside.md.qt_* MCP tools to screenshot real windows, walk the widget
tree, run qt_layout_check, and click/type through real states. Details:
references/qt-mcp.md.scripts/snap.py is a ~40-line, dependency-free template. Copy it into the
project (or run it in place), replace main() with your real screens, point it
at the project's apply_theme, and call shoot(widget, name, size) per state.
It writes PNGs into a shots/ folder for you to view.
Always render with the project's real theme applied — an unthemed snapshot hides spacing/contrast problems and invents others.
addStretch() between fields → floating content / dead space (S1).Expanding size policy and no max width → full-width boxes (L1).minimumWidth → panel clips instead of wrapping when narrowed (R1).QFormLayout.setLabelAlignment(0x0002) and similar raw-int enum calls →
TypeError on modern PySide6; pass Qt.AlignmentFlag (e.g. Qt.AlignRight).
The harness surfaces these because it actually instantiates the widget.A screenshot can't reveal "I clicked Assign and nothing happened" or "the button is dead when only one row is checked." Those are interaction bugs (rulebook section I). To catch them you must drive the UI, not just photograph it:
qt_click the checkbox, qt_click "Assign",
qt_screenshot before/after, qt_widget_details to confirm new state.snap.py, set the selection in code (check items / set the
model), call the same slot the button invokes, re-render, and assert the
status changed. Pair with the desktop-gui-testing skill for signal/slot and
geometry assertions.To let the running app itself host an agent that inspects and rewrites its own
UI (a toggleable "Design Mode"), see references/in-app-agent-sdk.md — the
Claude Agent SDK + the qt-mcp probe + these skills.
npx claudepluginhub mersadfathizadeh1995/programming_tools --plugin ui-reviewCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.