Extension: omni.kit.scene_view.xr_utils-1.0.2

Documentation Generated: Jul 18, 2026

WidgetComponent#

A WidgetComponent wraps any omni.ui.Widget subclass and gives it a physical size in 3D, a rendered texture resolution, and an update policy. It is the “what to draw” side of a UiContainer; the SpatialSource stack is the “where to draw” side.

panel_component = WidgetComponent(
    widget_type=InfoPanel,
    width=40.0,                # 40 cm wide
    height=20.0,               # 20 cm tall
    resolution_scale=4.0,
    unit_to_pixel_scale=2.0,
    update_policy=UpdatePolicy.ON_MOUSE_HOVERED,
)

The widget contract#

widget_type must be a class that can be constructed as widget_type(*widget_args, **widget_kwargs) and that builds an omni.ui tree in its __init__. Any subclass of omni.ui.Widget that does its layout work in the constructor (which is the standard pattern) will fit.

class InfoPanel(ui.Widget):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        with ui.Frame():
            with ui.VStack():
                ui.Label("Hello XR!", alignment=ui.Alignment.CENTER)
                ui.Label("Status: OK", alignment=ui.Alignment.CENTER)

To pass data to the widget at construction time, use widget_args or widget_kwargs. The label example in 03_prim_anchored_ui.py shows the keyword form:

WidgetComponent(
    widget_type=ObjectLabel,
    widget_kwargs={"prim_path": "/World/MyMachine"},
    ...
)

If post-construction setup needs a live widget reference (because it depends on attributes the constructor populates), supply a construct_callback:

def wire_up(widget: InfoPanel):
    widget.on_status_changed = ...

WidgetComponent(widget_type=InfoPanel, construct_callback=wire_up, ...)

Sizing model#

The component decouples three concepts:

Concept

Argument

What it controls

Physical size

width, height

How big the panel is in stage units (typically cm).

Texture density

resolution_scale

How many texture pixels render per stage unit; affects sharpness, not on-screen size.

UI scale

unit_to_pixel_scale

How many omni.ui pixels are packed into each stage unit; affects the perceived size of labels, buttons, and borders.

The rendered texture is computed as width * resolution_scale * unit_to_pixel_scale along each axis (and likewise for height). Working through the values from 01_basic_scene_ui.py:

width                = 100 cm
height               = 20  cm
resolution_scale     = 4.0
unit_to_pixel_scale  = 2.0

texture_width   = 100 * 4.0 * 2.0 = 800  px
texture_height  =  20 * 4.0 * 2.0 = 160  px

omni.ui layout space = 100 * 2.0 = 200 ui_units wide
                       20 * 2.0  =  40 ui_units tall

The omni.ui widget sees a 200×40 layout area; that area is rendered into an 800×160 texture (4× supersampling), then mapped onto a 100×20 cm rectangle in the scene. Adjust resolution_scale to change texture sharpness without changing the perceived size of UI details; adjust unit_to_pixel_scale to change how large UI details appear in world space.

Update policy#

update_policy controls when the underlying texture is re-rendered. The default, UpdatePolicy.ON_MOUSE_HOVERED, re-renders only while the panel is under the pointer or controller ray.

Policy

Behaviour

UpdatePolicy.ALWAYS

Re-renders every frame.

UpdatePolicy.ON_MOUSE_HOVERED (default)

Re-renders only while the panel is under the pointer / controller ray.

UpdatePolicy.ON_DEMAND

Re-renders only when scene_widget.invalidate() is called.

The full enum lives on omni.ui.scene.Widget.UpdatePolicy; this extension re-exports it as UpdatePolicy for convenience.

Triggering a rebuild#

When the data driving an omni.ui widget changes — e.g. a label needs new text — call invalidate() on the underlying scene widget:

label_component.scene_widget.invalidate()

This triggers omni.ui to rebuild the widget’s tree on the next frame, no matter what update_policy you chose. Call it in response to state changes that should produce visible updates.

The component exposes the live widget instance through the widget property once it has been built.

Tinting and color#

color applies a final multiplicative tint to the whole panel after omni.ui has rendered it, without rebuilding the widget tree.

WidgetComponent(widget_type=InfoPanel, color=[1.0, 0.9, 0.6], ...)

The default is [1.0] (white, no tint).

Where it fits#

WidgetComponent is a ManipulatorComponent that builds an omni.ui.scene.Widget inside the manipulator’s transform. It extends Area2DComponent, which gives it width, height, and origin / placement controls, and allows it to be the target of a Resize2DGestureHandler (see Advanced Manipulators).

See also#