MainLoop and Event Loops¶
MainLoop¶
- class urwid.MainLoop(widget: AbstractWidget, 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 | tuple[str, int, int, int]], list[int]], list[str | tuple[str, int, int, int]]] | 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 – the topmost widget used for painting the screen, stored as
widgetand may be modified. Must be a box widget.palette – initial palette for screen
screen – screen to use, default is a new
raw_display.Screeninstance; stored asscreenhandle_mouse –
Trueto askscreento process mouse eventsinput_filter – a function to filter input before sending it to
widget, called frominput_filter()unhandled_input – a function called when input is not handled by
widget, called fromunhandled_input()event_loop – if
screensupports external an event loop it may be given here, default is a newSelectEventLoopinstance; stored asevent_looppop_ups – True to wrap
widgetwith aPopUpTargetinstance 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
Note
Some
event_loopimplementations accept anasync defcallback in addition to a plain callable - see the specific implementation’s own documentation for whether it does, and how it runs one.set_alarm_in(),set_alarm_at(),watch_file()andwatch_pipe()all detect anasync defcallback and pass that detection through toevent_loop; whether it actually does anything still depends onevent_loop.Set up the main loop around a top-level widget, a screen and an event loop.
- Raises:
NotImplementedError – an event_loop is given but screen does not support external event loops.
- draw_screen() None¶
Render the widgets and paint the screen.
This method is called automatically from
entering_idle(), which runs whenever the event loop is about to go idle – including after handling input and after an alarm callback fires. So screen updates made from input handlers or alarm callbacks are redrawn automatically.If you modify the widgets displayed from somewhere else, such as another thread or a callback that does not go through the event loop’s idle handling, you will need to call this method yourself to repaint the screen.
- entering_idle() None¶
Call
draw_screen()to update the screen when anything has changed.This method is called whenever the event loop is about to enter the idle state.
- input_filter(keys: list[str | tuple[str, int, int, int]], raw: list[int]) list[str | tuple[str, int, int, int]]¶
Pass each of the input events and raw keystroke values through input_filter.
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.
- property pop_ups: bool¶
Return whether pop-up widgets opened via
PopUpLauncherare shown automatically.
- process_input(keys: Iterable[str | tuple[str, int, int, int]]) bool¶
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
Trueif any key was handled by a widget or theunhandled_input()method.- Raises:
TypeError – an item of keys is neither a key name nor a mouse event tuple.
- remove_alarm(handle: Any) bool¶
Remove an alarm. Return
Trueif handle was found,Falseotherwise.
- remove_watch_file(handle: Any) bool¶
Remove a watch file. Returns
Trueif the watch file exists,Falseotherwise.
- 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
Trueif the watch pipe exists,Falseotherwise
- run() None¶
Start the main loop handling input events and updating the screen.
The loop will continue until an
ExitMainLoopexception 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, andstop()once it’s finished.
- set_alarm_at(tm: float, callback: Callable[[Self, _T | None], Any], user_data: _T | None = None) Any¶
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 – time to call callback e.g.
time.time() + 5callback – function to call with two parameters: this main loop object and user_data
user_data – optional user data to pass to the callback
Note
callback may be an
async deffunction on anevent_loopimplementation that supports one; see the note onMainLoop.
- set_alarm_in(sec: float, callback: Callable[[Self, _T | None], Any], user_data: _T | None = None) Any¶
Schedule an alarm in sec seconds that will call callback from the within the
run()method.- Parameters:
sec – seconds until alarm
callback – function to call with two parameters: this main loop object and user_data
user_data – optional user data to pass to the callback
Note
callback may be an
async deffunction on anevent_loopimplementation that supports one; see the note onMainLoop.
- start() StoppingContext¶
Set up the main loop, hooking into the event loop where necessary.
Starts the
screenif 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.- Raises:
CantUseExternalLoop – the screen does not support external event loops.
- stop() None¶
Clean 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¶
Call the unhandled_input function passed to the constructor with any input not handled by the widgets.
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
Trueif it handled the input.
- watch_file(fd: int, callback: Callable[[], Any]) 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().Note
callback is passed to
event_loopunwrapped, so it may be anasync deffunction on anevent_loopimplementation that supports one; see the note onMainLoop.
- watch_pipe(callback: Callable[[bytes], bool | None]) int¶
Create a pipe used by another thread or subprocess to trigger callback in the main loop.
- Parameters:
callback – 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_loopis 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
Falsethen the watch will be removed fromevent_loopand the read end of the pipe will be closed. You are responsible for closing the write end of the pipe withos.close(fd).Note
callback may be an
async deffunction on anevent_loopimplementation that supports one; see the note onMainLoop.
- property widget: AbstractWidget¶
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().Initialize with no alarms or watched files yet.
- 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().
- Parameters:
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 – Executor to use for running the function
func – function to call
args – positional arguments to function
kwargs – keyword arguments to function
- Returns:
future object for the function call outcome.
- 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().
- Parameters:
fd – file descriptor to watch for input
callback – function to call when input is available
AsyncioEventLoop¶
- class urwid.AsyncioEventLoop(*, loop: AbstractEventLoop | None = None, **kwargs: Any)¶
Event loop based on the standard library
asynciomodule.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)
Note
alarm(),watch_file()andenter_idle()accept anasync defcallback in addition to a plain callable. A coroutine function is scheduled as anasyncio.Taskinstead of being called directly.Wrap loop, or the current asyncio event loop when none is given.
- 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().
- Parameters:
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: TimerHandle) 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.
- Raises:
BaseException – the exception that stopped the loop, once the loop has been left.
- 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 – Executor to use for running the function. Default asyncio executor is used if None.
func – function to call
args – arguments to function (positional only)
kwargs – keyword arguments to function (keyword only)
- Returns:
future object for the function call outcome.
- 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().
- Parameters:
fd – file descriptor to watch for input
callback – function to call when input is available
TrioEventLoop¶
- class urwid.TrioEventLoop¶
Event loop based on the
triomodule.triois an async library for Python 3.5 and later.Note
alarm(),watch_file()andenter_idle()accept anasync defcallback in addition to a plain callable. A coroutine function is scheduled as a task in the main loop’s nursery instead of being called directly.Initialize the Trio event loop.
- alarm(seconds: float, callback: Callable[[], Any]) trio.CancelScope¶
Call callback() a given time from now.
- Parameters:
seconds – time in seconds to wait before calling the callback
callback – function to call from the event loop
- Returns:
a handle that may be passed to remove_alarm()
No parameters are passed to the callback.
- enter_idle(callback: Callable[[], Any]) int¶
Call 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¶
Remove an alarm.
- Parameters:
handle – the handle of the alarm to remove
- remove_enter_idle(handle: int) bool¶
Remove an idle callback.
- Parameters:
handle – the handle of the idle callback to remove
- remove_watch_file(handle: CancelScope) bool¶
Remove 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¶
Start the event loop.
Exit the loop when any callback raises an exception. If ExitMainLoop is raised, exit cleanly.
- async run_async() None¶
Start the main loop and block 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 | SupportsFileno, callback: Callable[[], Any]) trio.CancelScope¶
Call 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.
Deprecated since version 4.1.7: This API will be removed in version 6.0.
Initialize a fresh GLib.MainLoop with no alarms or watched files yet.
- 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().
- Parameters:
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]]¶
Wrap f so that
ExitMainLoopraised inside it exits theGLibEventLoopcleanly.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: tuple[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.
- Raises:
BaseException – the exception that stopped the loop, once the loop has been left.
- run_in_executor(executor: Executor, func: Callable[_Spec, _T], *args: _Spec.args, **kwargs: _Spec.kwargs) Future[_T]¶
Run callable in executor.
- Parameters:
executor – Executor to use for running the function
func – function to call
args – positional arguments to function
kwargs – keyword arguments to function
- Returns:
future object for the function call outcome.
- set_signal_handler(signum: int, handler: Callable[[int, FrameType | None], Any] | int | signal.Handlers) None¶
Set 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()).- Parameters:
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().
- Parameters:
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.
Initialize the event loop, wrapping reactor or Twisted’s default reactor.
- Parameters:
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 settingmanage_reactor=Falseand 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().
- Parameters:
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]¶
Wrap f so that
ExitMainLoopraised inside it exits theTwistedEventLoopcleanly.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.
- Raises:
BaseException – the exception that stopped the loop, once the loop has been left.
- run_in_executor(executor: Executor, func: Callable[_Spec, _T], *args: _Spec.args, **kwargs: _Spec.kwargs) Future[_T] | asyncio.Future[_T]¶
Raise
NotImplementedError: use Twisted’s own thread pool API.- Raises:
NotImplementedError – Twisted has its own thread pool; use
threads.deferToThreadinstead.
- watch_file(fd: int, callback: Callable[[], _T]) 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().
- Parameters:
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.
Note
alarm(),watch_file()andenter_idle()accept anasync defcallback in addition to a plain callable. A coroutine function is scheduled as anasyncio.Taskon the IOLoop’s underlying asyncio loop instead of being called directly.Wrap loop, or Tornado’s current IOLoop when none is given.
- alarm(seconds: float, callback: Callable[[], Any]) object¶
Schedule callback to run after seconds and return a handle for
remove_alarm().
- enter_idle(callback: Callable[[], Any]) int¶
Add a callback for entering idle.
Returns a handle that may be passed to remove_idle()
- handle_exit(f: Callable[_Spec, _T]) Callable[_Spec, _T | Literal[False] | None]¶
Wrap f so that a raised exception stops the loop instead of propagating.
- remove_alarm(handle: object) bool¶
Cancel an alarm scheduled by
alarm(), returning whether it was still pending.
- remove_enter_idle(handle: int) bool¶
Remove an idle callback.
Returns True if the handle was removed.
- remove_watch_file(handle: int) bool¶
Stop watching a file descriptor registered by
watch_file(), returning whether it was watched.
- run() None¶
Start the event loop and run it until
ExitMainLoopis raised.- Raises:
BaseException – the exception that stopped the loop, once the loop has been left.
- run_in_executor(executor: Executor, func: Callable[_Spec, _T], *args: _Spec.args, **kwargs: _Spec.kwargs) asyncio.Future[_T]¶
Run callable in executor.
- Parameters:
executor – Executor to use for running the function
func – function to call
args – arguments to function (positional only)
kwargs – keyword arguments to function (keyword only)
- Returns:
future object for the function call outcome.
- watch_file(fd: int, callback: Callable[[], _T]) int¶
Call callback whenever fd is readable and return a handle for
remove_watch_file().
ZMQEventLoop¶
- class urwid.ZMQEventLoop¶
This class is an urwid event loop for ZeroMQ applications.
It is very similar to
SelectEventLoop, supporting the usualalarm()events and file watching (watch_file()) capabilities, but also incorporates the ability to watch zmq queues for events (watch_queue()).Note
alarm(),watch_file(),watch_queue()andenter_idle()accept anasync defcallback in addition to a plain callable.ZMQEventLoopruns on top of anasyncioloop (viazmq.asyncio.Poller), so a coroutine function is scheduled as a background task there instead of being called directly, the same way it would be on any otherasyncio-backed event loop.Initialize with a fresh zmq poller and no alarms or watched queues yet.
- 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
Trueif the alarm exists,Falseotherwise.
- remove_enter_idle(handle: int) bool¶
Remove an idle callback.
Returns
Trueif handle was removed,Falseotherwise.
- remove_watch_file(handle: int | SupportsFileno) bool¶
Remove a file from background polling.
Returns
Trueif the file was being monitored,Falseotherwise.
- remove_watch_queue(handle: Socket[Any]) bool¶
Remove a queue from background polling.
Returns
Trueif the queue was being monitored,Falseotherwise.
- run() None¶
Start the event loop.
Exit the loop when any callback raises an exception. If
ExitMainLoopis raised, exit cleanly.- Raises:
BaseException – the exception that stopped the loop, once the loop has been left.
- run_in_executor(executor: Executor, func: Callable[_Spec, _T], *args: _Spec.args, **kwargs: _Spec.kwargs) Future[_T]¶
Run callable in executor.
- Parameters:
executor – Executor to use for running the function
func – function to call
args – positional arguments to function
kwargs – keyword arguments to function
- Returns:
future object for the function call outcome.
- watch_file(fd: int | SupportsFileno, callback: Callable[[], typing.Any], flags: int = <PollEvent.POLLIN: 1>) int | SupportsFileno¶
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 toremove_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[typing.Any], callback: Callable[[], typing.Any], flags: int = <PollEvent.POLLIN: 1>) zmq.Socket[Any]¶
Call callback when zmq queue becomes ready to read or write.
flags controls the condition:
POLLIN(the default) watches for data to read,POLLOUTwatches for availability to write. No parameters are passed to the callback. Returns a handle that may be passed toremove_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).
- Raises:
ValueError – queue is already being watched.