Window Operations¶
Window operations address exactly one window, so they live on the Window
object as plain methods. Exiting the whole application is app-scoped and
lives on the App. See Multiple Windows for the
App / Window split.
Window methods¶
For code that holds a window (its own via Window.of(self), or one it
opened):
window = nv.Window.of(self)
window.maximize()
window.minimize()
window.restore() # exit full screen / restore size / bring back
window.full_screen() # enters full screen; restore() is the way back
window.center()
window.move_to(100, 80)
window.resize(1024, 768)
window.hide() # park the window; tree, state, and geometry survive
window.show() # bring it back, focused — or raise an already-visible one
window.close()
hide() is not a close: the window stays open (and keeps counting for the
App's exit policy), renders no frames while parked, and show() restores it
instantly. window.is_visible is the matching Observable[bool]. This pair
is what a tray-resident app is built on — see Tray Icon.
App methods¶
App.of(context) returns the running app, typed as nv.AppProtocol:
app = nv.App.of(self)
app.exit() # close every window and stop the loop
app.set_theme("dark") # a name, "light"/"dark", or a Theme instance
app.register_themes({...}) # name → Theme, for set_theme by name
In a ViewModel¶
A ViewModel should not depend on the full Window or App — annotate the
parameter as nv.WindowProtocol / nv.AppProtocol instead. Pass it per
method call, not in the constructor: a widget builds its ViewModel in
__init__, and .of(context) does not work that early (the widget is not
mounted yet). So the event handler resolves the object and hands it to the
ViewModel method:
class ShellViewModel:
def send_to_background(self, window: nv.WindowProtocol) -> None:
window.hide()
def quit(self, app: nv.AppProtocol) -> None:
app.exit()
class Shell(nv.ComposableWidget):
def __init__(self) -> None:
super().__init__()
self._vm = ShellViewModel()
def build(self):
return nv.Column(
children=[
nv.Button("Hide", on_click=lambda: self._vm.send_to_background(nv.Window.of(self))),
nv.Button("Quit", on_click=lambda: self._vm.quit(nv.App.of(self))),
],
)
A test calls the ViewModel methods with hand-written fakes — no widget tree
needed. WindowProtocol carries the operation methods above plus is_open,
is_visible, and the awaitable closed. AppProtocol carries exit,
set_theme, and register_themes.
Example Usage¶
import nuiitivet.material as nv
class WindowControls(nv.ComposableWidget):
def build(self):
return nv.Column(
children=[
nv.Text("Window Controls"),
nv.Button("Maximize", on_click=lambda: nv.Window.of(self).maximize()),
nv.Button("Minimize", on_click=lambda: nv.Window.of(self).minimize()),
nv.Button("Restore", on_click=lambda: nv.Window.of(self).restore()),
nv.Button("Center", on_click=lambda: nv.Window.of(self).center()),
nv.Button("Close", on_click=lambda: nv.Window.of(self).close()),
nv.Button("Quit", on_click=lambda: nv.App.of(self).exit()),
],
gap=10,
padding=20,
)
app = nv.App(nv.Window(content=WindowControls, width=400, height=400))
app.run()