Developer API Overview¶
This section covers the APIs available for developing plugins and extending VSView.
Most of these symbols are re-exported through the top-level vsview.api module for convenience.
Core & Proxies¶
Classes¶
PluginAPI
¶
PluginAPI(workspace: LoaderWorkspace[Any])
Bases: _PluginAPI
API for plugins to interact with the workspace.
Source code in src/vsview/app/plugins/_interface.py
Attributes¶
globalSettingsChanged
¶
globalSettingsChanged = Signal()
Signal to emit when global settings change.
localSettingsChanged
¶
Signal to emit when local settings change.
file_path
¶
file_path: Path | None
Return the file path of the currently loaded file, or None if not a file.
voutputs
¶
voutputs: list[VideoOutputProxy]
Return a dictionary of VideoOutputProxy objects for all tabs.
current_voutput
¶
current_voutput: VideoOutputProxy
Return the VideoOutput for the currently selected tab.
Functions¶
get_local_storage
¶
Return a path to a local storage directory for the given plugin, or None if the current workspace has no file path.
Source code in src/vsview/app/plugins/api.py
register_on_destroy
¶
Register a callback to be called before the workspace begins a reload or when the workspace is destroyed. This is generaly used to clean up VapourSynth resources.
Source code in src/vsview/app/plugins/api.py
vs_context
¶
vs_context() -> Iterator[None]
Context manager for using the VapourSynth environment of the workspace.
register_action
¶
register_action(
action_id: str,
action: QAction,
*,
context: ShortcutContext = WidgetWithChildrenShortcut,
) -> None
Register a QAction for shortcut management.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
action_id
|
str
|
The namespaced identifier (e.g., "my_plugin.do_thing"). |
required |
action
|
QAction
|
The QAction to manage. |
required |
context
|
ShortcutContext
|
The context in which the shortcut should be active. |
WidgetWithChildrenShortcut
|
Source code in src/vsview/app/plugins/api.py
register_shortcut
¶
register_shortcut(
action_id: str,
callback: Callable[[], Any],
parent: QWidget,
*,
context: ShortcutContext = WidgetWithChildrenShortcut,
) -> QShortcut
Create and register a QShortcut for shortcut management.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
action_id
|
str
|
The namespaced identifier (e.g., "my_plugin.do_thing"). |
required |
callback
|
Callable[[], Any]
|
The function to call when the shortcut is activated. |
required |
parent
|
QWidget
|
The parent widget that determines shortcut scope. |
required |
context
|
ShortcutContext
|
The context in which the shortcut should be active. |
WidgetWithChildrenShortcut
|
Returns:
| Type | Description |
|---|---|
QShortcut
|
The created QShortcut instance. |
Source code in src/vsview/app/plugins/api.py
get_shortcut_label
¶
Return the current shortcut's native display string or an empty string if no shortcut is assigned.
Source code in src/vsview/app/plugins/api.py
VideoOutputProxy
¶
VideoOutputProxy(
vs_index: int,
vs_name: str,
vs_output: VideoOutputTuple,
props: Mapping[int, Mapping[str, Any]],
framedurs: Sequence[float] | None,
cum_durations: Sequence[float] | None,
info: OutputInfo,
)
Read-only proxy for a video output.
Attributes¶
vs_output
¶
vs_output: VideoOutputTuple = field(hash=False, compare=False)
The object created by vapoursynth.get_outputs().
props
¶
Frame properties of the clip.
framedurs
¶
Frame durations of the clip.
cum_durations
¶
Cumulative durations of the clip.
Functions¶
time_to_frame
¶
time_to_frame(time: timedelta, fps: VideoOutputProxy | Fraction | None = None) -> Frame
Convert a time to a frame number for this output.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
time
|
timedelta
|
The time to convert. |
required |
fps
|
VideoOutputProxy | Fraction | None
|
Optional override for FPS/duration context. |
None
|
Source code in src/vsview/app/plugins/api.py
frame_to_time
¶
frame_to_time(frame: int, fps: VideoOutputProxy | Fraction | None = None) -> Time
Convert a frame number to time for this output.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
frame
|
int
|
The frame number to convert. |
required |
fps
|
VideoOutputProxy | Fraction | None
|
Optional override for FPS/duration context. |
None
|
Source code in src/vsview/app/plugins/api.py
AudioOutputProxy
¶
Read-only proxy for an audio output.
GraphicsViewProxy
¶
GraphicsViewProxy(workspace: LoaderWorkspace[Any], view: GraphicsView)
Bases: _GraphicsViewProxy
Proxy for a graphics view.
Source code in src/vsview/app/plugins/_interface.py
Attributes¶
Classes¶
ViewportProxy
¶
Bases: _ViewportProxy
Proxy for a viewport.
Source code in src/vsview/app/plugins/_interface.py
map_from_global
¶Map global coordinates to the current view's local coordinates.
Source code in src/vsview/app/plugins/api.py
set_cursor
¶set_cursor(cursor: QCursor | CursorShape) -> None
Set the cursor for the current view's viewport.
Source code in src/vsview/app/plugins/api.py
Functions¶
map_to_scene
¶
Map coordinates to this view's scene.
Source code in src/vsview/app/plugins/api.py
map_from_scene
¶
Map coordinates from view's scene.
Source code in src/vsview/app/plugins/api.py
PluginSettings
¶
Bases: Generic[TGlobalSettings, TLocalSettings]
Settings wrapper providing lazy, always-fresh access.
Returns None if no settings model is defined for the scope.
Source code in src/vsview/app/plugins/api.py
WidgetPluginBase
¶
Bases: _PluginBase[TGlobalSettings, TLocalSettings], QWidget
Base class for all widget plugins.
Source code in src/vsview/app/plugins/api.py
Attributes¶
shortcuts
¶
shortcuts: Sequence[ActionDefinition] = ()
Keyboard shortcuts for this plugin.
Each ActionDefinition ID must start with "{identifier}." prefix.
settings
¶
settings: PluginSettings[TGlobalSettings, TLocalSettings]
Get the settings wrapper for lazy, always-fresh access.
Functions¶
update_global_settings
¶
update_global_settings(**updates: Any) -> None
Update specific global settings fields and trigger persistence.
on_current_voutput_changed
¶
on_current_voutput_changed(voutput: VideoOutputProxy, tab_index: int) -> None
Called when the current video output changes.
Execution Thread: Main or Background.
If you need to update the UI, use the @run_in_loop decorator.
Source code in src/vsview/app/plugins/api.py
on_current_frame_changed
¶
on_current_frame_changed(n: int) -> None
Called when the current frame changes.
Execution Thread: Main or Background.
If you need to update the UI, use the @run_in_loop decorator.
on_playback_started
¶
on_playback_stopped
¶
on_view_context_menu
¶
on_view_context_menu(event: QContextMenuEvent) -> None
Called when a context menu of the current viewis requested.
The event is forwarded BEFORE the view processes it.
Execution Thread: Main.
on_view_mouse_moved
¶
on_view_mouse_moved(event: QMouseEvent) -> None
Called when the mouse of the current view is moved.
The event is forwarded AFTER the view processes it.
Execution Thread: Main.
on_view_mouse_pressed
¶
on_view_mouse_pressed(event: QMouseEvent) -> None
Called when the mouse of the current view is pressed.
The event is forwarded AFTER the view processes it.
Execution Thread: Main.
on_view_mouse_released
¶
on_view_mouse_released(event: QMouseEvent) -> None
Called when the mouse of the current view is released.
The event is forwarded AFTER the view processes it.
Execution Thread: Main.
on_view_key_press
¶
on_view_key_press(event: QKeyEvent) -> None
Called when a key is pressed in the current view.
The event is forwarded AFTER the view processes it.
Execution Thread: Main.
NodeProcessor
¶
NodeProcessor(api: PluginAPI)
Bases: _PluginBase[TGlobalSettings, TLocalSettings], Generic[NodeT, TGlobalSettings, TLocalSettings]
Interface for objects that process VapourSynth nodes.
Source code in src/vsview/app/plugins/api.py
Attributes¶
shortcuts
¶
shortcuts: Sequence[ActionDefinition] = ()
Keyboard shortcuts for this plugin.
Each ActionDefinition ID must start with "{identifier}." prefix.
settings
¶
settings: PluginSettings[TGlobalSettings, TLocalSettings]
Get the settings wrapper for lazy, always-fresh access.
Functions¶
update_global_settings
¶
update_global_settings(**updates: Any) -> None
Update specific global settings fields and trigger persistence.
prepare
¶
Process the input node and return a modified node of the same type.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
node
|
NodeT
|
The raw input node (VideoNode or AudioNode). |
required |
Returns:
| Type | Description |
|---|---|
NodeT
|
The processed node compatible with the player's output requirements. |
Source code in src/vsview/app/plugins/api.py
ActionDefinition
¶
LocalSettingsModel
¶
Bases: BaseModel
Base class for settings with optional local overrides.
Fields set to None fall back to the corresponding global value.
Functions¶
resolve
¶
Resolve global settings with local overrides applied.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
global_settings
|
BaseModel
|
Source of default values. |
required |
Returns:
| Type | Description |
|---|---|
Self
|
A new instance with all fields resolved. |
Source code in src/vsview/app/plugins/api.py
Custom Widgets¶
Classes¶
Accordion
¶
Bases: QFrame
Source code in src/vsview/app/views/components.py
AnimatedToggle
¶
AnimatedToggle(parent: QWidget | None = None)
Bases: QCheckBox
Source code in src/vsview/app/views/components.py
SegmentedControl
¶
SegmentedControl(
labels: Sequence[str],
parent: QWidget | None = None,
direction: Direction = LeftToRight,
)
Bases: QWidget
A segmented control widget for binary choices.
Emits segmentChanged signal with the index of the selected segment.
Source code in src/vsview/app/views/components.py
FrameEdit
¶
FrameEdit(parent: QWidget)
TimeEdit
¶
TimeEdit(parent: QWidget)
Bases: QTimeEdit
Source code in src/vsview/app/views/timeline.py
BaseGraphicsView
¶
Bases: QGraphicsView
Source code in src/vsview/app/views/video.py
PluginGraphicsView
¶
Bases: BaseGraphicsView
Graphics view for plugins.
Source code in src/vsview/app/plugins/api.py
Functions¶
refresh
¶
on_current_voutput_changed
¶
on_current_voutput_changed(voutput: VideoOutputProxy, tab_index: int) -> None
Called when the current video output changes.
Warning: Do not call self.refresh() here, as it will cause an infinite loop.
If you need to update the display manually, use self.update_display().
Execution Thread: Main or Background.
If you need to update the UI, use the @run_in_loop decorator.
Source code in src/vsview/app/plugins/api.py
on_current_frame_changed
¶
on_current_frame_changed(n: int, f: VideoFrame) -> None
Called when the current frame changes.
n is the frame number and f is the packed VideoFrame in GRAY32 format.
Warning: Do not call self.refresh() here, as it will cause an infinite loop.
If you need to update the display manually, use self.update_display().
Execution Thread: Main or Background.
If you need to update the UI, use the @run_in_loop decorator.
Source code in src/vsview/app/plugins/api.py
get_node
¶
Override this to transform the clip before it is displayed. By default, it returns the clip as-is.
UI Settings¶
Classes¶
WidgetMetadata
¶
WidgetMetadata(
label: str,
*,
tooltip: str | None = None,
to_ui: Callable[[Any], Any] | None = None,
from_ui: Callable[[Any], Any] | None = None,
)
Bases: ABC
Base class for widget metadata.
Checkbox
¶
Checkbox(
label: str,
text: str,
*,
tooltip: str | None = None,
to_ui: Callable[[Any], Any] | None = None,
from_ui: Callable[[Any], Any] | None = None,
)
Bases: WidgetMetadata[QCheckBox]
Checkbox widget metadata.
Dropdown
¶
Dropdown(
label: str,
items: Iterable[tuple[str, Any]],
*,
tooltip: str | None = None,
to_ui: Callable[[Any], Any] | None = None,
from_ui: Callable[[Any], Any] | None = None,
)
Bases: WidgetMetadata[QComboBox]
Dropdown/ComboBox widget metadata.
Spin
¶
Spin(
label: str,
min: int = 0,
max: int = 100,
suffix: str = "",
*,
tooltip: str | None = None,
to_ui: Callable[[Any], Any] | None = None,
from_ui: Callable[[Any], Any] | None = None,
)
Bases: WidgetMetadata[QSpinBox]
SpinBox widget metadata for integers.
DoubleSpin
¶
DoubleSpin(
label: str,
min: float = 0.0,
max: float = 100.0,
suffix: str = "",
decimals: int = 2,
*,
tooltip: str | None = None,
to_ui: Callable[[Any], Any] | None = None,
from_ui: Callable[[Any], Any] | None = None,
)
Bases: WidgetMetadata[QDoubleSpinBox]
DoubleSpinBox widget metadata for floats.
PlainTextEdit
¶
PlainTextEdit(
label: str,
value_type: type[T],
max_height: int = 120,
*,
tooltip: str | None = None,
to_ui: Callable[[Any], Any] | None = None,
from_ui: Callable[[Any], Any] | None = None,
default_value: T | None = None,
)
Bases: WidgetMetadata[QPlainTextEdit]
PlainTextEdit widget for editing a list of values (one per line).
Timeline & Playback¶
Classes¶
Time
¶
Bases: timedelta
Time type.
Functions¶
to_qtime
¶
to_qtime() -> QTime
Convert a Time object to a QTime object.
Source code in src/vsview/app/views/timeline.py
to_ts
¶
Formats a timedelta object using standard Python formatting syntax.
Available keys: {D} : Days {H} : Hours (0-23) {M} : Minutes (0-59) {S} : Seconds (0-59) {ms} : Milliseconds (0-999) {us} : Microseconds (0-999999)
Total duration keys: {th} : Total Hours (e.g., 100 hours) {tm} : Total Minutes {ts} : Total Seconds
Example
# 1. Standard Clock format (Padding with :02d)
# Output: "26:05:03"
print(time.to_ts(td, "{th:02d}:{M:02d}:{S:02d}"))
# 2. Detailed format
# Output: "1 days, 02 hours, 05 minutes"
print(time.to_ts(td, "{D} days, {H:02d} hours, {M:02d} minutes"))
# 3. With Milliseconds
# Output: "02:05:03.500"
print(time.to_ts(td, "{H:02d}:{M:02d}:{S:02d}.{ms:03d}"))
Source code in src/vsview/app/views/timeline.py
from_qtime
¶
Utilities¶
Attributes¶
Classes¶
IconReloadMixin
¶
Mixin for QWidget subclasses with automatic icon hot-reload support.
Mix this with any QWidget subclass to get automatic icon updates when global settings (icon provider/weight) change.
Example:
class MyWidget(QWidget, IconReloadMixin):
def __init__(self, parent: QWidget | None = None) -> None:
super().__init__(parent)
# Button is automatically registered for icon hot-reload
self.btn = self.make_tool_button(IconName.LINK, "Link", self)
Source code in src/vsview/assets/utils.py
Functions¶
register_icon_button
¶
register_icon_button(
button: QToolButton,
icon_name: IconName,
icon_size: QSize = QSize(20, 20),
color_role: ColorRole = ToolTipText,
icon_states: Mapping[tuple[Mode, State], ColorRole | tuple[ColorGroup, ColorRole]]
| None = None,
) -> None
Register a button for automatic icon reload when settings change.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
button
|
QToolButton
|
The QToolButton to update. |
required |
icon_name
|
IconName
|
The IconName to use for the button. |
required |
icon_size
|
QSize
|
Size for the icon. |
QSize(20, 20)
|
color_role
|
ColorRole
|
Palette color role for simple icons (used when icon_states is None). |
ToolTipText
|
icon_states
|
Mapping[tuple[Mode, State], ColorRole | tuple[ColorGroup, ColorRole]] | None
|
Full mapping of (QIcon.Mode, QIcon.State) -> QPalette.ColorRole. Allows complete control over icon appearance for all Qt states. Example: |
None
|
Source code in src/vsview/assets/utils.py
register_icon_action
¶
register_icon_action(
action: QAction,
icon_name: IconName,
icon_size: QSize = QSize(20, 20),
color_role: ColorRole = ToolTipText,
icon_states: Mapping[tuple[Mode, State], ColorRole | tuple[ColorGroup, ColorRole]]
| None = None,
) -> None
Register a QAction for automatic icon reload.
Source code in src/vsview/assets/utils.py
register_icon_callback
¶
register_icon_callback(callback: Callable[[], None]) -> None
Register a custom callback for icon reloading.
Use this for complex icons that don't fit the standard button pattern (e.g., play/pause with different icons per state, spinner animations).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
callback
|
Callable[[], None]
|
A callable that reloads the icon(s). |
required |
Source code in src/vsview/assets/utils.py
make_icon
¶
make_icon(
icons: tuple[IconName, QColor] | dict[tuple[Mode, State], tuple[IconName, QColor]],
size: QSize | None = None,
) -> QIcon
Create a QIcon from either: - a single (IconName, color) tuple - or a dict mapping (mode, state) -> (IconName, color)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
icons
|
tuple[IconName, QColor] | dict[tuple[Mode, State], tuple[IconName, QColor]]
|
Icon specification using IconName enum.
Simple usage: |
required |
size
|
QSize | None
|
Target size for SVG rendering (for crisp output). |
None
|
Source code in src/vsview/assets/utils.py
make_tool_button
¶
make_tool_button(
icon: IconName | QIcon,
tooltip: str,
parent: QWidget | None = None,
*,
checkable: bool = False,
checked: bool = False,
register_icon: bool = True,
icon_size: QSize = QSize(20, 20),
color: QColor | None = None,
color_role: ColorRole = ToolTipText,
icon_states: Mapping[tuple[Mode, State], ColorRole | tuple[ColorGroup, ColorRole]]
| None = None,
) -> QToolButton
Create a tool button with an icon and automatically register it for hot-reload when the icon is an IconName.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
icon
|
IconName | QIcon
|
The icon to display (IconName for auto-creation, or QIcon for pre-made). |
required |
tooltip
|
str
|
Tooltip text for the button. |
required |
parent
|
QWidget | None
|
Parent widget. |
None
|
checkable
|
bool
|
Whether the button is checkable. |
False
|
checked
|
bool
|
Initial checked state (only applies if checkable=True). |
False
|
icon_size
|
QSize
|
Size for the icon. |
QSize(20, 20)
|
color
|
QColor | None
|
Explicit color for the icon (overrides color_role). |
None
|
color_role
|
ColorRole
|
Palette color role for the icon (default: ToolTipText). Used when icon_states is None. |
ToolTipText
|
icon_states
|
Mapping[tuple[Mode, State], ColorRole | tuple[ColorGroup, ColorRole]] | None
|
Full mapping of (QIcon.Mode, QIcon.State) -> QPalette.ColorRole. Allows complete control over icon appearance for all Qt states:
Example: |
None
|
Returns:
| Type | Description |
|---|---|
QToolButton
|
A configured QToolButton instance. |
Source code in src/vsview/assets/utils.py
make_action
¶
make_action(
icon: IconName | QIcon,
tooltip: str,
parent: QWidget | None = None,
*,
checkable: bool = False,
checked: bool = False,
register_icon: bool = True,
icon_size: QSize = QSize(20, 20),
color: QColor | None = None,
color_role: ColorRole = ToolTipText,
icon_states: Mapping[tuple[Mode, State], ColorRole | tuple[ColorGroup, ColorRole]]
| None = None,
) -> QAction
Create a QAction with an icon and automatically register it for hot-reload when the icon is an IconName.
Source code in src/vsview/assets/utils.py
Functions¶
run_in_background
¶
run_in_background(*, name: str) -> _DecoratorFuture
Executes the decorated function in a background thread (via QThreadPool)
using the QtEventLoop's to_thread logic.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
func
|
Any
|
The function to wrap (when used as |
None
|
name
|
str | None
|
Optional thread name for logging (when used as |
None
|
Returns:
| Type | Description |
|---|---|
Any
|
A future object representing the result of the execution. |
Usage:
Source code in src/vsview/vsenv/loop.py
run_in_loop
¶
run_in_loop(*, return_future: Literal[True]) -> _DecoratorFuture
run_in_loop(*, return_future: Literal[False]) -> _DecoratorDirect
run_in_loop(*, return_future: bool) -> _DecoratorFuture | _DecoratorDirect
Decorator. Executes the decorated function within the QtEventLoop (Main Thread).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
func
|
Any
|
The function to wrap (when used as |
None
|
return_future
|
bool
|
If False, blocks and returns R directly. |
True
|
Returns:
| Type | Description |
|---|---|
Any
|
A future object or the result directly, depending on return_future. |
Usage: