MainLoop and Event Loops

MainLoop

class urwid.MainLoop(widget: Widget, palette: Iterable[tuple[str, str] | tuple[str, str, str] | tuple[str, str, str, str] | tuple[str, str, str, str, str, str]] = (), screen: BaseScreen | None = None, handle_mouse: bool = True, input_filter: Callable[[list[str], list[int]], list[str]] | None = None, unhandled_input: Callable[[str | tuple[str, int, int, int]], bool | None] | None = None, event_loop: EventLoop | None = None, pop_ups: bool = False)

This is the standard main loop implementation for a single interactive session.

Parameters:
  • widget (widget instance) – the topmost widget used for painting the screen, stored as widget and may be modified. Must be a box widget.

  • palette (iterable of palette entries) – initial palette for screen

  • screen (display module screen instance) – screen to use, default is a new raw_display.Screen instance; stored as screen

  • handle_mouse (bool) – True to ask screen to process mouse events

  • input_filter (callable) – a function to filter input before sending it to widget, called from input_filter()

  • unhandled_input (callable) – a function called when input is not handled by widget, called from unhandled_input()

  • event_loop (event loop instance) – if screen supports external an event loop it may be given here, default is a new SelectEventLoop instance; stored as event_loop

  • pop_ups (boolean) – True to wrap widget with a PopUpTarget instance to allow any widget to open a pop-up anywhere on the screen

screen

The screen object this main loop uses for screen updates and reading input

event_loop

The event loop object this main loop uses for waiting on alarms and IO

draw_screen() None

Render the widgets and paint the screen. This method is called automatically from entering_idle().

If you modify the widgets displayed outside of handling input or responding to an alarm you will need to call this method yourself to repaint the screen.

entering_idle() None

This method is called whenever the event loop is about to enter the idle state. draw_screen() is called here to update the screen when anything has changed.

input_filter(keys: list[str], raw: list[int]) list[str]

This function is passed each all the input events and raw keystroke values. These values are passed to the input_filter function passed to the constructor. That function must return a list of keys to be passed to the widgets to handle. If no input_filter was defined this implementation will return all the input events.

process_input(keys: Iterable[str | tuple[str, int, int, int]]) bool

This method will pass keyboard input and mouse events to widget. This method is called automatically from the run() method when there is input, but may also be called to simulate input from the user.

keys is a list of input returned from screen’s get_input() or get_input_nonblocking() methods.

Returns True if any key was handled by a widget or the unhandled_input() method.

remove_alarm(handle) bool

Remove an alarm. Return True if handle was found, False otherwise.

remove_watch_file(handle)

Remove a watch file. Returns True if the watch file exists, False otherwise.

remove_watch_pipe(write_fd: int) bool

Close the read end of the pipe and remove the watch created by watch_pipe().

..note:: You are responsible for closing the write end of the pipe.

Returns True if the watch pipe exists, False otherwise

run() None

Start the main loop handling input events and updating the screen. The loop will continue until an ExitMainLoop exception is raised.

If you would prefer to manage the event loop yourself, don’t use this method. Instead, call start() before starting the event loop, and stop() once it’s finished.

set_alarm_at(tm: float, callback: Callable[[Self, _T], Any], user_data: _T = None)

Schedule an alarm at tm time that will call callback from the within the run() function. Returns a handle that may be passed to remove_alarm().

Parameters:
  • tm (float) – time to call callback e.g. time.time() + 5

  • callback (callable) – function to call with two parameters: this main loop object and user_data

  • user_data (object) – optional user data to pass to the callback

set_alarm_in(sec: float, callback: Callable[[Self, _T], Any], user_data: _T = None)

Schedule an alarm in sec seconds that will call callback from the within the run() method.

Parameters:
  • sec (float) – seconds until alarm

  • callback (callable) – function to call with two parameters: this main loop object and user_data

  • user_data (object) – optional user data to pass to the callback

start() StoppingContext

Sets up the main loop, hooking into the event loop where necessary. Starts the screen if it hasn’t already been started.

If you want to control starting and stopping the event loop yourself, you should call this method before starting, and call stop once the loop has finished. You may also use this method as a context manager, which will stop the loop automatically at the end of the block:

with main_loop.start():

Note that some event loop implementations don’t handle exceptions specially if you manage the event loop yourself. In particular, the Twisted and asyncio loops won’t stop automatically when ExitMainLoop (or anything else) is raised.

stop() None

Cleans up any hooks added to the event loop. Only call this if you’re managing the event loop yourself, after the loop stops.

unhandled_input(data: str | tuple[str, int, int, int]) bool | None

This function is called with any input that was not handled by the widgets, and calls the unhandled_input function passed to the constructor. If no unhandled_input was defined then the input will be ignored.

input is the keyboard or mouse input.

The unhandled_input function should return True if it handled the input.

watch_file(fd: int, callback: Callable[[], Any])

Call callback when fd has some data to read. No parameters are passed to callback.

Returns a handle that may be passed to remove_watch_file().

watch_pipe(callback: Callable[[bytes], bool | None]) int

Create a pipe for use by a subprocess or thread to trigger a callback in the process/thread running the main loop.

Parameters:

callback (callable) – function taking one parameter to call from within the process/thread running the main loop

This method returns a file descriptor attached to the write end of a pipe. The read end of the pipe is added to the list of files event_loop is watching. When data is written to the pipe the callback function will be called and passed a single value containing data read from the pipe.

This method may be used any time you want to update widgets from another thread or subprocess.

Data may be written to the returned file descriptor with os.write(fd, data). Ensure that data is less than 512 bytes (or 4K on Linux) so that the callback will be triggered just once with the complete value of data passed in.

If the callback returns False then the watch will be removed from event_loop and the read end of the pipe will be closed. You are responsible for closing the write end of the pipe with os.close(fd).

property widget: Widget

Property for the topmost widget used to draw the screen. This must be a box widget.

SelectEventLoop

class urwid.SelectEventLoop

Event loop based on selectors.DefaultSelector.select()

alarm(seconds: float, callback: Callable[[], Any]) tuple[float, int, Callable[[], Any]]

Call callback() a given time from now. No parameters are passed to callback.

Returns a handle that may be passed to remove_alarm()

seconds – floating point time to wait before calling callback callback – function to call from event loop

enter_idle(callback: Callable[[], Any]) int

Add a callback for entering idle.

Returns a handle that may be passed to remove_idle()

remove_alarm(handle: tuple[float, int, Callable[[], Any]]) bool

Remove an alarm.

Returns True if the alarm exists, False otherwise

remove_enter_idle(handle: int) bool

Remove an idle callback.

Returns True if the handle was removed.

remove_watch_file(handle: int) bool

Remove an input file.

Returns True if the input file exists, False otherwise

run() None

Start the event loop. Exit the loop when any callback raises an exception. If ExitMainLoop is raised, exit cleanly.

run_in_executor(executor: Executor, func: Callable[_Spec, _T], *args: _Spec.args, **kwargs: _Spec.kwargs) Future[_T]

Run callable in executor.

Parameters:
  • executor (concurrent.futures.Executor) – Executor to use for running the function

  • func (Callable) – function to call

  • args (object) – positional arguments to function

  • kwargs (object) – keyword arguments to function

Returns:

future object for the function call outcome.

Return type:

concurrent.futures.Future

watch_file(fd: int, callback: Callable[[], Any]) int

Call callback() when fd has some data to read. No parameters are passed to callback.

Returns a handle that may be passed to remove_watch_file()

fd – file descriptor to watch for input callback – function to call when input is available

AsyncioEventLoop

class urwid.AsyncioEventLoop(*, loop: AbstractEventLoop | None = None, **kwargs)

Event loop based on the standard library asyncio module.

Warning

Under Windows, AsyncioEventLoop globally enforces WindowsSelectorEventLoopPolicy as a side-effect of creating a class instance. Original event loop policy is restored in destructor method.

Note

If you make any changes to the urwid state outside of it handling input or responding to alarms (for example, from asyncio.Task running in background), and wish the screen to be redrawn, you must call MainLoop.draw_screen() method of the main loop manually.

A good way to do this:

asyncio.get_event_loop().call_soon(main_loop.draw_screen)

alarm(seconds: float, callback: Callable[[], Any]) asyncio.TimerHandle

Call callback() a given time from now. No parameters are passed to callback.

Returns a handle that may be passed to remove_alarm()

seconds – time in seconds to wait before calling callback callback – function to call from event loop

enter_idle(callback: Callable[[], Any]) int

Add a callback for entering idle.

Returns a handle that may be passed to remove_enter_idle()

remove_alarm(handle) bool

Remove an alarm.

Returns True if the alarm exists, False otherwise

remove_enter_idle(handle: int) bool

Remove an idle callback.

Returns True if the handle was removed.

remove_watch_file(handle: int) bool

Remove an input file.

Returns True if the input file exists, False otherwise

run() None

Start the event loop.

Exit the loop when any callback raises an exception. If ExitMainLoop is raised, exit cleanly.

run_in_executor(executor: Executor | None, func: Callable[_Spec, _T], *args: _Spec.args, **kwargs: _Spec.kwargs) asyncio.Future[_T]

Run callable in executor.

Parameters:
  • executor (concurrent.futures.Executor | None) – Executor to use for running the function. Default asyncio executor is used if None.

  • func (Callable) – function to call

  • args (object) – arguments to function (positional only)

  • kwargs (object) – keyword arguments to function (keyword only)

Returns:

future object for the function call outcome.

Return type:

asyncio.Future

watch_file(fd: int, callback: Callable[[], Any]) int

Call callback() when fd has some data to read. No parameters are passed to callback.

Returns a handle that may be passed to remove_watch_file()

fd – file descriptor to watch for input callback – function to call when input is available

TrioEventLoop

class urwid.TrioEventLoop

Event loop based on the trio module.

trio is an async library for Python 3.5 and later.

Constructor.

alarm(seconds: float, callback: Callable[[], Any]) trio.CancelScope

Calls callback() a given time from now.

Parameters:
  • seconds (float) – time in seconds to wait before calling the callback

  • callback (Callable[[], Any]) – function to call from the event loop

Returns:

a handle that may be passed to remove_alarm()

Return type:

trio.CancelScope

No parameters are passed to the callback.

enter_idle(callback: Callable[[], Any]) int

Calls callback() when the event loop enters the idle state.

There is no such thing as being idle in a Trio event loop so we simulate it by repeatedly calling callback() with a short delay.

remove_alarm(handle: CancelScope) bool

Removes an alarm.

Parameters:

handle: the handle of the alarm to remove

remove_enter_idle(handle: int) bool

Removes an idle callback.

Parameters:

handle: the handle of the idle callback to remove

remove_watch_file(handle: CancelScope) bool

Removes a file descriptor being watched for input.

Parameters:

handle: the handle of the file descriptor callback to remove

Returns:

True if the file descriptor was watched, False otherwise

run() None

Starts the event loop. Exits the loop when any callback raises an exception. If ExitMainLoop is raised, exits cleanly.

async run_async() None

Starts the main loop and blocks asynchronously until the main loop exits.

This allows one to embed an urwid app in a Trio app even if the Trio event loop is already running. Example:

with trio.open_nursery() as nursery:
    event_loop = urwid.TrioEventLoop()

    # [...launch other async tasks in the nursery...]

    loop = urwid.MainLoop(widget, event_loop=event_loop)
    with loop.start():
        await event_loop.run_async()

    nursery.cancel_scope.cancel()
watch_file(fd: int | io.IOBase, callback: Callable[[], Any]) trio.CancelScope

Calls callback() when the given file descriptor has some data to read. No parameters are passed to the callback.

Parameters:

fd: file descriptor to watch for input callback: function to call when some input is available

Returns:

a handle that may be passed to remove_watch_file()

GLibEventLoop

class urwid.GLibEventLoop

Event loop based on GLib.MainLoop

alarm(seconds: float, callback: Callable[[], Any]) tuple[int, Callable[[], Any]]

Call callback() a given time from now. No parameters are passed to callback.

Returns a handle that may be passed to remove_alarm()

seconds – floating point time to wait before calling callback callback – function to call from event loop

enter_idle(callback: Callable[[], Any]) int

Add a callback for entering idle.

Returns a handle that may be passed to remove_enter_idle()

handle_exit(f: Callable[_Spec, _T]) Callable[_Spec, _T | Literal[False]]

Decorator that cleanly exits the GLibEventLoop if ExitMainLoop is thrown inside of the wrapped function. Store the exception info if some other exception occurs, it will be reraised after the loop quits.

f – function to be wrapped

remove_alarm(handle) bool

Remove an alarm.

Returns True if the alarm exists, False otherwise

remove_enter_idle(handle) bool

Remove an idle callback.

Returns True if the handle was removed.

remove_watch_file(handle: int) bool

Remove an input file.

Returns True if the input file exists, False otherwise

run() None

Start the event loop. Exit the loop when any callback raises an exception. If ExitMainLoop is raised, exit cleanly.

run_in_executor(executor: Executor, func: Callable[_Spec, _T], *args: _Spec.args, **kwargs: _Spec.kwargs) Future[_T]

Run callable in executor.

Parameters:
  • executor (concurrent.futures.Executor) – Executor to use for running the function

  • func (Callable) – function to call

  • args (object) – positional arguments to function

  • kwargs (object) – keyword arguments to function

Returns:

future object for the function call outcome.

Return type:

concurrent.futures.Future

set_signal_handler(signum: int, handler: Callable[[int, FrameType | None], Any] | int | signal.Handlers) None

Sets the signal handler for signal signum.

Warning

Because this method uses the GLib-specific unix_signal_add function, its behaviour is different than signal.signal().

If signum is not SIGHUP, SIGINT, SIGTERM, SIGUSR1, SIGUSR2 or SIGWINCH, this method performs no actions and immediately returns None.

Returns None in all cases (unlike signal.signal()).

signum – signal number handler – function (taking signum as its single argument), or signal.SIG_IGN, or signal.SIG_DFL

watch_file(fd: int, callback: Callable[[], Any]) int

Call callback() when fd has some data to read. No parameters are passed to callback.

Returns a handle that may be passed to remove_watch_file()

fd – file descriptor to watch for input callback – function to call when input is available

TwistedEventLoop

class urwid.TwistedEventLoop(reactor: ReactorBase | None = None, manage_reactor: bool = True)

Event loop based on Twisted

Parameters:

reactor (twisted.internet.reactor.) – reactor to use

Param:

manage_reactor: True if you want this event loop to run and stop the reactor.

Warning

Twisted’s reactor doesn’t like to be stopped and run again. If you need to stop and run your MainLoop, consider setting manage_reactor=False and take care of running/stopping the reactor at the beginning/ending of your program yourself.

You can also forego using MainLoop’s run() entirely, and instead call start() and stop() before and after starting the reactor.

alarm(seconds: float, callback: Callable[[], Any]) DelayedCall

Call callback() a given time from now. No parameters are passed to callback.

Returns a handle that may be passed to remove_alarm()

seconds – floating point time to wait before calling callback callback – function to call from event loop

enter_idle(callback: Callable[[], Any]) int

Add a callback for entering idle.

Returns a handle that may be passed to remove_enter_idle()

handle_exit(f: Callable[_Spec, _T], enable_idle: bool = True) Callable[_Spec, _T | None]

Decorator that cleanly exits the TwistedEventLoop if ExitMainLoop is thrown inside of the wrapped function. Store the exception info if some other exception occurs, it will be reraised after the loop quits.

f – function to be wrapped

remove_alarm(handle: DelayedCall) bool

Remove an alarm.

Returns True if the alarm exists, False otherwise

remove_enter_idle(handle: int) bool

Remove an idle callback.

Returns True if the handle was removed.

remove_watch_file(handle: int) bool

Remove an input file.

Returns True if the input file exists, False otherwise

run() None

Start the event loop. Exit the loop when any callback raises an exception. If ExitMainLoop is raised, exit cleanly.

run_in_executor(executor: Executor, func: Callable[..., _T], *args: object, **kwargs: object) Future[_T]

Run callable in executor if supported.

Parameters:
  • executor (concurrent.futures.Executor) – Executor to use for running the function

  • func (Callable) – function to call

  • args (object) – arguments to function (positional only)

  • kwargs (object) – keyword arguments to function (keyword only)

Returns:

future object for the function call outcome. (exact future type depends on the event loop type)

Return type:

concurrent.futures.Future | asyncio.Future

watch_file(fd: int, callback: Callable[[], Any]) int

Call callback() when fd has some data to read. No parameters are passed to callback.

Returns a handle that may be passed to remove_watch_file()

fd – file descriptor to watch for input callback – function to call when input is available

TornadoEventLoop

class urwid.TornadoEventLoop(loop: IOLoop | None = None)

This is an Urwid-specific event loop to plug into its MainLoop. It acts as an adaptor for Tornado’s IOLoop which does all heavy lifting except idle-callbacks.

alarm(seconds: float, callback: Callable[[], Any])

Call callback() a given time from now. No parameters are passed to callback.

This method has no default implementation.

Returns a handle that may be passed to remove_alarm()

seconds – floating point time to wait before calling callback callback – function to call from event loop

enter_idle(callback: Callable[[], Any]) int

Add a callback for entering idle.

Returns a handle that may be passed to remove_idle()

remove_alarm(handle: object) bool

Remove an alarm.

This method has no default implementation.

Returns True if the alarm exists, False otherwise

remove_enter_idle(handle: int) bool

Remove an idle callback.

Returns True if the handle was removed.

remove_watch_file(handle: int) bool

Remove an input file.

This method has no default implementation.

Returns True if the input file exists, False otherwise

run() None

Start the event loop. Exit the loop when any callback raises an exception. If ExitMainLoop is raised, exit cleanly.

This method has no default implementation.

run_in_executor(executor: Executor, func: Callable[_Spec, _T], *args: _Spec.args, **kwargs: _Spec.kwargs) asyncio.Future[_T]

Run callable in executor.

Parameters:
  • executor (concurrent.futures.Executor) – Executor to use for running the function

  • func (Callable) – function to call

  • args (object) – arguments to function (positional only)

  • kwargs (object) – keyword arguments to function (keyword only)

Returns:

future object for the function call outcome.

Return type:

asyncio.Future

watch_file(fd: int, callback: Callable[[], _T]) int

Call callback() when fd has some data to read. No parameters are passed to callback.

This method has no default implementation.

Returns a handle that may be passed to remove_watch_file()

fd – file descriptor to watch for input callback – function to call when input is available

ZMQEventLoop

class urwid.ZMQEventLoop

This class is an urwid event loop for ZeroMQ applications. It is very similar to SelectEventLoop, supporting the usual alarm() events and file watching (watch_file()) capabilities, but also incorporates the ability to watch zmq queues for events (watch_queue()).

alarm(seconds: float, callback: Callable[[], Any]) ZMQAlarmHandle

Call callback a given time from now. No parameters are passed to callback. Returns a handle that may be passed to remove_alarm().

Parameters:
  • seconds (float) – floating point time to wait before calling callback.

  • callback – function to call from event loop.

enter_idle(callback: Callable[[], Any]) int

Add a callback to be executed when the event loop detects it is idle. Returns a handle that may be passed to remove_enter_idle().

remove_alarm(handle: ZMQAlarmHandle) bool

Remove an alarm. Returns True if the alarm exists, False otherwise.

remove_enter_idle(handle: int) bool

Remove an idle callback. Returns True if handle was removed, False otherwise.

remove_watch_file(handle: io.TextIOWrapper) bool

Remove a file from background polling. Returns True if the file was being monitored, False otherwise.

remove_watch_queue(handle: Socket) bool

Remove a queue from background polling. Returns True if the queue was being monitored, False otherwise.

run() None

Start the event loop. Exit the loop when any callback raises an exception. If ExitMainLoop is raised, exit cleanly.

run_in_executor(executor: Executor, func: Callable[_Spec, _T], *args: _Spec.args, **kwargs: _Spec.kwargs) Future[_T]

Run callable in executor.

Parameters:
  • executor (concurrent.futures.Executor) – Executor to use for running the function

  • func (Callable) – function to call

  • args (object) – positional arguments to function

  • kwargs (object) – keyword arguments to function

Returns:

future object for the function call outcome.

Return type:

concurrent.futures.Future

watch_file(fd: int | io.TextIOWrapper, callback: Callable[[], Any], flags: int = PollEvent.POLLIN) io.TextIOWrapper

Call callback when fd has some data to read. No parameters are passed to the callback. The flags are as for watch_queue(). Returns a handle that may be passed to remove_watch_file().

Parameters:
  • fd – The file-like object, or fileno to monitor.

  • callback – The function to call when the file has data available.

  • flags (int) – The condition to monitor on the file (defaults to POLLIN).

watch_queue(queue: zmq.Socket, callback: Callable[[], Any], flags: int = PollEvent.POLLIN) zmq.Socket

Call callback when zmq queue has something to read (when flags is set to POLLIN, the default) or is available to write (when flags is set to POLLOUT). No parameters are passed to the callback. Returns a handle that may be passed to remove_watch_queue().

Parameters:
  • queue – The zmq queue to poll.

  • callback – The function to call when the poll is successful.

  • flags (int) – The condition to monitor on the queue (defaults to POLLIN).