Display Modules

class urwid.BaseScreen

Base class for Screen classes (display.raw.Screen, …, etc.).

Initialize an unstarted screen with an empty palette.

clear() → None

Clear the screen if possible.

Force the screen to be completely repainted on the next call to draw_screen().

abstractmethod draw_screen(size: tuple[int, int], canvas: Canvas) → None

Draw canvas of the given size to the screen. Subclasses must implement this method.

get_cols_rows() → tuple[int, int]

Return the terminal dimensions (num columns, num rows).

Default (fallback) is 80x24.

property palette: Mapping[Hashable, PaletteEntrySpecs]

Return a read-only view of the registered palette entries.

The view follows later changes to the palette. Change the palette with register_palette() and register_palette_entry().

>>> from urwid.display.html_fragment import HtmlGenerator
>>> screen = HtmlGenerator()
>>> screen.register_palette_entry("title", "white", "dark blue")
>>> screen.palette["title"].basic
AttrSpec('white', 'dark blue')
Returns:

per entry name, the specifications it is drawn with; None names the default attribute.

register_palette(palette: Iterable[PaletteEntry], *, replace: bool = False) → None

Register a set of palette entries.

With replace, the entries that palette does not name are removed once all of its entries are registered. A removed name is drawn in the terminal’s default colors, as a name that was never registered is. The None entry is kept unless palette names it, so the screen keeps its default attribute.

>>> from urwid.display.html_fragment import HtmlGenerator
>>> screen = HtmlGenerator()
>>> screen.register_palette([("title", "white", "dark blue"), ("body", "black", "light gray")])
>>> screen.register_palette([("body", "white", "black")], replace=True)
>>> list(screen.palette)
[None, 'body']
Parameters:
  • palette – a list of (name, like_other_name) or (name, foreground, background, mono, foreground_high, background_high) tuples

  • replace – remove the entries that palette does not name

Raises:

ScreenError –

an entry is neither a 2-, 3-, 4- nor 6-tuple, or copies a name that is not registered yet. The entries before it stay registered, and with replace no entry is removed.

The (name, like_other_name) format will copy the settings from the palette entry like_other_name, which must appear before this tuple in the list.

The mono and foreground/background_high values are optional ie. the second tuple format may have 3, 4 or 6 values. See register_palette_entry() for a description of the tuple values.

register_palette_entry(name: Hashable, foreground: str, background: str, mono: str | tuple[str, ...] | None = None, foreground_high: str | None = None, background_high: str | None = None) → None

Register a single palette entry.

Parameters:
  • name – new entry/attribute name, any hashable value; None names the default attribute

  • foreground –

    a string containing a comma-separated foreground color and settings

    Color values: ‘default’ (use the terminal’s default foreground), ‘inherit’ (take the color from the enclosing attribute), ‘black’, ‘dark red’, ‘dark green’, ‘brown’, ‘dark blue’, ‘dark magenta’, ‘dark cyan’, ‘light gray’, ‘dark gray’, ‘light red’, ‘light green’, ‘yellow’, ‘light blue’, ‘light magenta’, ‘light cyan’, ‘white’

    Settings: ‘bold’, ‘underline’, ‘blink’, ‘standout’, ‘strikethrough’

    Some terminals use ‘bold’ for bright colors. Most terminals ignore the ‘blink’ setting. If the color is not given then ‘default’ will be assumed.

  • background –

    a string containing the background color

    Background color values: ‘default’ (use the terminal’s default background), ‘inherit’ (take the color from the enclosing attribute), ‘black’, ‘dark red’, ‘dark green’, ‘brown’, ‘dark blue’, ‘dark magenta’, ‘dark cyan’, ‘light gray’

  • mono –

    a comma-separated string containing monochrome terminal settings (see “Settings” above.)

    None = no terminal settings (same as ‘default’)

  • foreground_high –

    a string containing a comma-separated foreground color and settings, standard foreground colors (see “Color values” above) or high-colors may be used

    High-color example values: ‘#009’ (0% red, 0% green, 60% red, like HTML colors) ‘#fcc’ (100% red, 80% green, 80% blue) ‘g40’ (40% gray, decimal), ‘g#cc’ (80% gray, hex), ‘#000’, ‘g0’, ‘g#00’ (black), ‘#fff’, ‘g100’, ‘g#ff’ (white) ‘h8’ (color number 8), ‘h255’ (color number 255)

    None = use foreground parameter value

  • background_high –

    a string containing the background color, standard background colors (see “Background colors” above) or high-colors (see “High-color example values” above) may be used

    None = use background parameter value

resolve_attr(attr: Hashable, index: int) → AttrSpec

Return the AttrSpec to draw a canvas run with display attribute attr.

Starting from the palette entry of None, each layer of attr (a palette name, an AttrSpec or a LayeredAttr), outermost first, is placed over the result so far with AttrSpec.layered_over(). A name missing from the palette is drawn with ‘default’ colors, hiding the layers under it.

Parameters:
  • attr – display attribute of a canvas run

  • index – position in the palette entry tuple: 0 for 16 colors, 1 for monochrome, 2 for 88 colors, 3 for 256 colors, 4 for true color

Raises:

IndexError – index is outside 0-4 and a layer is a palette name.

set_mouse_tracking(enable: bool = True) → None

Enable or disable tracking of mouse movement events. A no-op here; subclasses override it.

start(*args: Any, **kwargs: Any) → StoppingContext

Set up the screen.

If the screen has already been started, does nothing.

May be used as a context manager, in which case stop() will automatically be called at the end of the block:

with screen.start():

…

You shouldn’t override this method in a subclass; instead, override _start().

property started: bool

Return whether the screen has been started and not yet stopped.

stop() → None

Tear down the screen if it has been started.

Emits INPUT_DESCRIPTORS_CHANGED once the screen is marked stopped, so an event loop hooked to the screen stops watching its input.

You shouldn’t override this method; override _stop().

class urwid.display.PaletteEntrySpecs(basic: AttrSpec, mono: AttrSpec, high_88: AttrSpec, high_256: AttrSpec, high_true: AttrSpec)

The specifications one palette entry is drawn with, one per number of colors.

The position of each field is the index BaseScreen.resolve_attr() takes.

Create new instance of PaletteEntrySpecs(basic, mono, high_88, high_256, high_true)

basic: AttrSpec

16 colors

high_256: AttrSpec

256 colors

high_88: AttrSpec

88 colors

high_true: AttrSpec

true color

mono: AttrSpec

monochrome

RAW display

class urwid.display.raw.Screen(input: SupportsFileno = <_io.TextIOWrapper name='<stdin>' mode='r' encoding='utf-8'>, output: TextWriter = <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>, bracketed_paste_mode: bool | None = None, focus_reporting: bool | None = None, extended_keys: bool = False)

Raw screen backend that drives a real POSIX terminal.

Initialize a screen that directly prints escape codes to an output terminal.

Parameters:
  • input – the terminal input, read through its file descriptor.

  • output – the terminal output, which the escape codes are written to.

  • bracketed_paste_mode – enable bracketed paste (begin/end paste keystrokes). None (default) auto-detects via DECRQM and enables it once confirmed supported; pass True/False to force it without probing.

  • focus_reporting – enable focus reporting (focus in/focus out keystrokes). None (default) auto-detects via DECRQM and enables it once confirmed supported; pass True/False to force it without probing.

  • extended_keys – report the keys the legacy encodings cannot tell apart, such as 'ctrl enter' and 'ctrl i' apart from 'tab', through the keyboard protocol the terminal supports. Ctrl+C and Ctrl+Z then arrive as keys instead of signals; see Extended Keys.

Note

on terminal-generated signals: putting the terminal into cbreak mode (see start()) does not clear the tty’s ISIG flag, so the line discipline still turns Ctrl+C and Ctrl+Z into SIGINT and SIGTSTP and delivers them to this process (urwid/urwid#1268). SIGINT is left for the application or its event loop to handle as it sees fit. SIGTSTP is handled by this class: signal_init() installs a handler that wakes the input loop, which restores the terminal before actually suspending the process, then puts the terminal back into cbreak/alternate-buffer mode and forces a redraw on resume, so a stray Ctrl+Z does not leave a stale, unresponsive frame painted on screen. The suspend therefore waits until the application next reads input, through get_input() or the callback hook_event_loop() registers. Applications that install their own SIGTSTP handler on top of this one should chain to the previous handler (as this class does) rather than replacing it outright, and multithreaded applications must call signal_init() and signal_restore() from the main thread, since only the main thread can receive process signals. start() also clears the IEXTEN flag, which cbreak mode leaves on, so on macOS and the BSDs Ctrl+V, Ctrl+O and Ctrl+Y reach the application instead of being handled by the terminal driver. It clears FLUSHO as well: a Ctrl+O typed before the start can leave that output discard on, and without IEXTEN no Ctrl+O can turn it off. stop() restores both flags.

get_available_raw_input() → list[int]

Return any currently available input, then carry out a suspend requested by SIGTSTP.

The screen is stopped before the process suspends itself, and restarted and fully redrawn on resume. The flag is checked after the wake-up socket is drained, so a later request keeps its wake-up pending.

get_cols_rows() → tuple[int, int]

Return the terminal dimensions (num columns, num rows).

get_input_descriptors() → list[SupportsFileno | int]

Return a list of integer file descriptors that should be polled in external event loops.

Used to check for user input. Use this method if you are implementing your own event loop.

This method is only called by hook_event_loop, so if you override that, you can safely ignore this.

hook_event_loop(event_loop: EventLoop, callback: Callable[[_DecodedInput, list[int]], Any]) → None

Register the given callback with the event loop, to be called with new input whenever it’s available.

The callback should be passed a list of processed keys and a list of unprocessed keycodes.

Subclasses may wish to use parse_input to wrap the callback.

Deprecated since version 5.0: A subclass that defines get_input_nonblocking() is still polled through it. Override get_available_raw_input() instead. This API will be removed in version 7.0.

signal_init() → None

Set the SIGWINCH and SIGTSTP signal handlers, called in the startup of run wrapper.

Override this function to call from main thread in threaded applications.

signal_restore() → None

Restore the SIGTSTP and SIGWINCH signal handlers, called in the finally block of run wrapper.

Override this function to call from main thread in threaded applications.

unhook_event_loop(event_loop: EventLoop) → None

Remove any hooks added by hook_event_loop.

Curses display

class urwid.display.curses.Screen

Screen backend that drives the real terminal through the curses module.

Outside Windows, start() clears the IEXTEN and FLUSHO flags of a terminal input, as urwid.display.raw.Screen does, and stop() restores them.

Initialize an unstarted curses screen with no color pairs allocated yet.

clear() → None

Force the screen to be completely repainted on the next call to draw_screen().

draw_screen(size: tuple[int, int], canvas: Canvas) → None

Paint screen with rendered canvas.

Raises:
  • RuntimeError – the screen has not been started.

  • ValueError – canvas does not match size, or a run carries an unknown character set.

  • TypeError – a text run is not a byte string.

get_cols_rows() → tuple[int, int]

Return the terminal dimensions (num columns, num rows).

get_input(raw_keys: Literal[False]) → _DecodedInput
get_input(raw_keys: Literal[True]) → tuple[_DecodedInput, list[int]]

Return pending input as a list.

Parameters:

raw_keys – return raw keycodes as well as translated versions

Raises:

RuntimeError – the screen has not been started.

This function will immediately return all the input since the last time it was called. If there is no input pending it will wait before returning an empty list. The wait time may be configured with the set_input_timeouts function.

If raw_keys is False (default) this function will return a list of keys pressed. If raw_keys is True this function will return a ( keys pressed, raw keycodes ) tuple instead.

Examples of keys returned:

  • ASCII printable characters: space, a, 0, A, -, /

  • ASCII control characters: tab, enter

  • Escape sequences: up, page up, home, insert, f1

  • Key combinations: shift f1, meta a, ctrl b

  • Window events: "window resize"

Other characters, decoded from the terminal encoding (UTF-8, or a single- or double-byte encoding):

  • Unicode characters: “u00a5”, “u253c”, “u4e2d”

Examples of mouse events returned:

  • Mouse button press: (‘mouse press’, 1, 15, 13),

    (‘meta mouse press’, 2, 17, 23)

  • Mouse button release: (‘mouse release’, 1, 18, 13),

    (‘ctrl mouse release’, 2, 17, 23)

The button number is a MouseButton value.

set_input_timeouts(max_wait: float | None = None, complete_wait: float = 0.1, resize_wait: float = 0.1) → None

Set the get_input timeout values.

All values have a granularity of 0.1s, ie. any value between 0.15 and 0.05 will be treated as 0.1 and any value less than 0.05 will be treated as 0. Waits longer than 25.5 seconds are split into multiple curses waits.

Parameters:
  • max_wait – amount of time in seconds to wait for input when there is no input pending, wait forever if None

  • complete_wait – amount of time in seconds to wait when get_input detects an incomplete escape sequence at the end of the available input

  • resize_wait – amount of time in seconds to wait for more input after receiving two screen resize requests in a row to stop urwid from consuming 100% cpu during a gradual window resize operation

set_mouse_tracking(enable: bool = True) → None

Enable mouse tracking.

After calling this function get_input will include mouse click events along with keystrokes.

Raises:

NotImplementedError – enable is false while tracking is on; tracking cannot be turned off.

WEB display

class urwid.display.web.Screen

Screen backend that renders to a browser client over the web server’s polling/streaming connection.

Initialize an unstarted screen defaulting to true color.

clear() → None

Force the screen to be completely repainted on the next call to draw_screen().

(does nothing for web_display)

draw_screen(size: tuple[int, int], canvas: Canvas) → None

Send a screen update to the client.

Raises:

ValueError – canvas does not have the number of rows given by size.

get_cols_rows() → tuple[int, int]

Return the screen size.

get_input(raw_keys: Literal[False]) → list[str]
get_input(raw_keys: Literal[True]) → tuple[list[str], list[int]]

Return pending input as a list.

set_input_timeouts(*args: Any) → None

Not supported for web display.

set_mouse_tracking(enable: bool = True) → None

Not yet implemented.

start(*args: Any, **kwargs: Any) → StoppingContext

Read the initial screen size, generate a unique id and handle cleanup when fn exits.

web_display.set_preferences(..) must be called before calling this function for the preferences to take effect

Raises:
  • RuntimeError – the HTTP_X_URWID_METHOD environment variable is not set.

  • PermissionError – the session directory is not private, see _session_dir().

property started: bool

Return whether this screen has been started.

stop() → None

Restore settings and clean up.

tty_signal_keys(*args: Any, **vargs: Any) → None

Do nothing.

WebSocket display

class urwid.display.websocket.Screen(transport: Transport, *, cols: int = 80, rows: int = 24, max_cols: int = 223, max_rows: int = 223)

Screen that draws into one browser page through a Transport.

It takes input only from feed(), so it needs no file descriptor, and it runs on any event loop. Input reaches the main loop through an alarm of the event loop, which is what makes the main loop redraw.

ExitMainLoop raised by an input handler ends this session only: the screen closes its transport. Any other exception from an input handler or a redraw, and ExitMainLoop from an alarm, stops the event loop, and with it every session it runs, unless the main loop runs on a GuardedEventLoop whose handler calls close().

Call every method from the thread that runs the event loop.

Important

Do not use paused() with this screen: there is no terminal to hand over.

Initialize an unstarted screen that sends through transport.

Parameters:
  • transport – the connection to the page.

  • cols – the width until the page reports its own; at most max_cols is used.

  • rows – the height until the page reports its own; at most max_rows is used.

  • max_cols – the largest width the page may report; pass the same value to html_page().

  • max_rows – the largest height the page may report; pass the same value to html_page().

Raises:

ValueError – cols, rows, max_cols or max_rows is less than 1.

clear() → None

Force the screen to be completely repainted on the next call to draw_screen().

close() → None

End the session: drop the queued input, ignore further messages and close the transport.

property closed: bool

Return whether close() has ended the session.

draw_screen(size: tuple[int, int], canvas: Canvas) → None

Send the rows of canvas that the page does not show yet.

Nothing is sent once the session is closed.

Raises:

ValueError – canvas does not have the number of rows given by size.

feed(message: str | bytes) → None

Check one message from the page and queue the input it carries.

A message is a JSON object of one of these forms, with no other keys:

  • {"type": "key", "key": <name>}, where the name is an urwid key name the page script can send: a named key such as "page up" or "f5", or one character that is not a control character, after the modifiers "shift ", "meta " and "ctrl " in that order.

  • {"type": "resize", "cols": <int>, "rows": <int>} with both sizes at least 1. A size above the screen’s max_cols or max_rows is reduced to that limit.

  • {"type": "mouse", "event": <name>, "button": <int>, "col": <int>, "row": <int>}, where the name is "mouse press", "mouse release" or "mouse drag" after the same modifiers as a key name, the button is 1 to 9 as MouseButton numbers them, and the column and row are at least 0. A position outside the screen is moved to its nearest edge. It reaches the main loop as an (event, button, col, row) tuple, and is dropped while mouse tracking is off. A drag replaces a drag of the same button that still waits for the main loop, and a wheel press is dropped while MAX_PENDING_INPUT inputs wait, so a fast drag or wheel does not end the session.

Messages that arrive after close() are ignored.

Parameters:

message – the content of one WebSocket message.

Raises:

InvalidMessageError – the message is binary, longer than MAX_MESSAGE_LENGTH, not of one of the forms above, or more than MAX_PENDING_INPUT inputs wait for the main loop.

get_cols_rows() → tuple[int, int]

Return the size the page reported last, or the size given to the constructor.

While queued input is handed to the main loop, it is the size that input arrived at instead, so the main loop lays out input that arrived before a later resize at the size the page had then.

hook_event_loop(event_loop: EventLoop, callback: Callable[[list[str | tuple[str, int, int, int]], list[int]], Any]) → None

Hand the input from feed() to callback through alarms of event_loop.

Parameters:
  • event_loop – the event loop the main loop runs on.

  • callback – called with the key names and mouse events, and an empty list of raw key codes.

set_mouse_tracking(enable: bool = True) → None

Pass the mouse events the page sends to the main loop, or drop them.

The page sends them in either case, so it takes the mouse buttons for the application all the time.

unhook_event_loop(event_loop: EventLoop) → None

Stop handing input to the callback given to hook_event_loop().

Input that has not been handed over yet waits for the next hook_event_loop().

class urwid.display.websocket.Transport(*args, **kwargs)

The connection to one browser page, implemented by the adapter for its server library.

close() → None

Close the connection.

It does nothing when the connection is already closed or closing.

send(text: str) → None

Send text to the page as one text message, without blocking.

It may drop the text when the connection is already closing.

exception urwid.display.websocket.InvalidMessageError

A message from the browser does not follow the protocol of the page script.

urwid.display.websocket.html_page(title: str, websocket_path: str, *, max_cols: int = 223, max_rows: int = 223) → str

Return the HTML page that connects to a Screen.

The page has no inline script or style, so it works under a Content-Security-Policy that allows scripts and styles from 'self' only. It loads the STATIC_FILES by names relative to its own URL. It carries the largest screen size, so the page fits its screen area to the size the screen uses and does not report the mouse beyond it.

>>> page = html_page("Demo & test", "ws")
>>> "<title>Demo &amp; test</title>" in page
True
>>> 'data-websocket-path="ws"' in page
True
Parameters:
  • title – the application name shown in the title and above the screen; it is escaped.

  • websocket_path – the URL of the WebSocket, relative to the page’s URL; it is escaped.

  • max_cols – the largest width; the same value as the screen’s max_cols.

  • max_rows – the largest height; the same value as the screen’s max_rows.

Raises:

ValueError – max_cols or max_rows is less than 1.

urwid.display.websocket.STATIC_FILES: Final[Mapping[str, StaticFile]]

the files the page loads, by the name the page uses relative to its own URL

class urwid.display.websocket.StaticFile(content_type: str, source: str)

A file the page loads from the directory it was served from.

read() → bytes

Return the content of the file.

urwid.display.websocket.MAX_COLS: Final = 223

the default largest width, in columns: the largest an X10 mouse report can address in a terminal

urwid.display.websocket.MAX_ROWS: Final = 223

the default largest height, in rows, for the same reason

urwid.display.websocket.MAX_MESSAGE_LENGTH: Final = 256

the longest message from the browser, in characters; a valid message is far shorter

urwid.display.websocket.MAX_PENDING_INPUT: Final = 64

the most keys and mouse events received and not yet handed to the main loop

HTML fragment

class urwid.display.html_fragment.HtmlGenerator

Screen backend that renders each displayed frame as an HTML fragment instead of a real terminal.

Initialize the simulated screen with a 16-color palette.

draw_screen(size: tuple[int, int], canvas: Canvas) → None

Create an html fragment from the render object.

Append it to HtmlGenerator.fragments list.

Raises:

ValueError – canvas does not have the number of rows given by size.

get_cols_rows() → tuple[int, int]

Return the next screen size in HtmlGenerator.sizes.

Raises:

HtmlGeneratorSimulationError – the list of simulated sizes is exhausted.

get_input(raw_keys: Literal[False]) → _DecodedInput
get_input(raw_keys: Literal[True]) → tuple[_DecodedInput, list[int]]

Return the next list of keypresses in HtmlGenerator.keys.

Raises:

ExitMainLoop – the list of simulated key presses is exhausted.

reset_default_terminal_palette(*args: Any) → None

Do nothing; this simulated screen has no real terminal palette to reset.

set_input_timeouts(*args: Any) → None

Do nothing; this simulated screen has no real input source to configure timeouts on.

set_terminal_properties(colors: int | None = None, bright_is_bold: bool | None = None, has_underline: bool | None = None) → None

Store the given terminal capabilities, keeping each one unchanged where it is left as None.

urwid.display.html_fragment.screenshot_init(sizes: list[tuple[int, int]], keys: list[_DecodedInput]) → None

Replace display.curses.Screen and display.raw.Screen class with HtmlGenerator.

Call this function before executing an application that uses display.curses.Screen to have that code use HtmlGenerator instead.

Parameters:
  • sizes – list of ( columns, rows ) tuples to be returned by each call to HtmlGenerator.get_cols_rows()

  • keys – list of lists of keys to be returned by each call to HtmlGenerator.get_input()

Raises:
  • TypeError – sizes is not a list of integer pairs, or keys is not a list of lists of strings.

  • ValueError – a size has a non-positive number of columns or rows.

Lists of keys may include “window resize” to force the application to call get_cols_rows and read a new screen size.

For example, the following call will prepare an application to:
  1. start in 80x25 with its first call to get_cols_rows()

  2. take a screenshot when it calls draw_screen(..)

  3. simulate 5 down keys from get_input()

  4. take a screenshot when it calls draw_screen(..)

  5. simulate keys a, b, c and a "window resize" event

  6. resize to 20x10 on its second call to get_cols_rows()

  7. take a screenshot when it calls draw_screen(..)

  8. simulate a “Q” keypress to quit the application

screenshot_init( [ (80,25), (20,10) ],

[ [“down”]*5, [“a”,”b”,”c”,”window resize”], [“Q”] ] )

Deprecated since version 4.1.8: Patching display.curses.Screen/display.raw.Screen in place is deprecated and will stop working in version 6.0. Assign HtmlGenerator to your application’s screen manually instead.

urwid.display.html_fragment.screenshot_collect() → list[str]

Return screenshots as a list of HTML fragments.

LCD display

class urwid.display.lcd.LCDScreen

Base class for LCD-based screens.

Deprecated since version 5.1.0: The LCD display module will be removed in version 6.0, with no replacement.

Set up the screen state shared by every display module.

get_cols_rows() → tuple[int, int]

Return the size of the LCD display as (cols, rows).

reset_default_terminal_palette(*args: Any) → None

Reset the terminal’s default palette. A no-op here; an LCD screen has no palette to reset.

set_input_timeouts(*args: Any) → None

Set the maximum time in seconds to wait for input characters. A no-op here.

set_terminal_properties(colors: Literal[1, 16, 88, 256, 16777216] | None = None, bright_is_bold: bool | None = None, has_underline: bool | None = None) → None

Set terminal attributes. A no-op here; an LCD screen has no colors, bold, or underline to configure.

class urwid.display.lcd.CFLCDScreen(device_path: str, baud: int)

Common methods for Crystal Fonts LCD displays.

Deprecated since version 5.1.0: The LCD display module will be removed in version 6.0, with no replacement.

Open the serial connection.

Parameters:
  • device_path – serial device to talk to, e.g. /dev/ttyUSB0

  • baud – baud rate

exception InvalidPacket

Raised when a packet is longer than the protocol allows, or its CRC does not match.

exception MoreDataRequired

Raised when the buffered data does not yet hold a complete packet.

classmethod get_crc(buf: Iterable[int]) → bytes

Return the 16-bit CRC of buf, as the two bytes sent in a packet’s checksum field.

class urwid.display.lcd.CF635Screen(device_path: str, baud: int = 115200, repeat_delay: float = 0.5, repeat_next: float = 0.125, key_map: Iterable[str] = ('up', 'down', 'left', 'right', 'enter', 'esc'))

Crystal Fontz 635 display.

20x4 character display + cursor no foreground/background colors or settings supported

see CGROM for a list of close Unicode matches to characters available

6 button input up, down, left, right, enter (check mark), exit (cross)

Deprecated since version 5.1.0: The LCD display module will be removed in version 6.0, with no replacement.

Open the serial connection and set up key repeat handling.

Parameters:
  • device_path – serial device to talk to, e.g. /dev/ttyUSB0

  • baud – baud rate

  • repeat_delay – seconds to wait before starting to repeat keys

  • repeat_next – time between each repeated key

  • key_map – the keys to send for this device’s buttons

ACK_RESENDS: int = 3

How many times a command is sent again before it is dropped.

ACK_TIMEOUT: float = 0.25

Seconds to wait for a command’s ACK before sending the command again.

draw_screen(size: tuple[int, int], canvas: Canvas) → None

Send canvas to the display.

Raises:

ValueError – size is not the fixed size of this display.

get_input_descriptors() → list[int]

Return the descriptor of the serial device.

get_input_nonblocking() → tuple[float | None, list[str], list[int]]

Return a (next_input_timeout, keys_pressed, raw_keycodes) tuple.

The protocol for our device requires waiting for acks between each command, so this method responds to those as well as key press and release events.

Key repeat events are simulated here as the device doesn’t send any for us.

raw_keycodes are the bytes of messages we received, which might not seem to have any correspondence to keys_pressed.

hook_event_loop(event_loop: EventLoop, callback: Callable[[list[str], list[int]], Any]) → None

Watch the serial device on event_loop and pass what get_input_nonblocking() returns to callback.

The device’s answers, an ACK or an error response, are answered with the next queued command as they arrive, and a held key is repeated from an alarm, since the device sends no repeats. A command whose ACK does not arrive within ACK_TIMEOUT seconds is sent again, up to ACK_RESENDS times, and then dropped, so the queue never stops.

Logged:

  • a warning when the device stops answering, and an info message when it answers again;

  • an error the first time the device refuses a command with a given code.

program_cgram(index: int, data: Sequence[int]) → None

Program character data.

Characters available as chr(0) through chr(7), and repeated as chr(8) through chr(15).

Parameters:
  • index – 0 to 7 index of character to program

  • data – list of 8, 6-bit integer values top to bottom with MSB on the left side of the character.

Raises:

ValueError – index is outside 0-7, or data is not 8 rows.

queue_command(command: int, data: bytearray) → None

Queue command with data for sending, sending it immediately if no command is awaiting an ACK.

set_backlight(value: int) → None

Set backlight brightness.

Parameters:

value – 0 to 100

Raises:

ValueError – value is outside 0-100.

set_cursor_style(style: Literal[1, 2, 3, 4]) → None

Set the cursor style.

Parameters:

style – CURSOR_BLINKING_BLOCK, CURSOR_UNDERSCORE, CURSOR_BLINKING_BLOCK_UNDERSCORE or CURSOR_INVERTING_BLINKING_BLOCK

Raises:

ValueError – style is not one of the four cursor styles.

set_lcd_contrast(value: int) → None

Set the LCD contrast.

Parameters:

value – 0 to 255

Raises:

ValueError – value is outside 0-255.

set_led_pin(led: Literal[0, 1, 2, 3], rg: Literal[0, 1], value: int) → None

Set an LED pin’s brightness.

Parameters:
  • led – 0 to 3

  • rg – 0 for red, 1 for green

  • value – 0 to 100

Raises:

ValueError – led is outside 0-3, rg is not 0 or 1, or value is outside 0-100.

unhook_event_loop(event_loop: EventLoop) → None

Remove the watch and the alarms that hook_event_loop() and the commands sent since added.

class urwid.display.lcd.KeyRepeatSimulator(repeat_delay: float, repeat_next: float)

Provide simulated repeat key events when given press and release events.

If two or more keys are pressed, disable repeating until all keys are released.

Deprecated since version 5.1.0: The LCD display module will be removed in version 6.0, with no replacement.

Set up the repeat timing.

Parameters:
  • repeat_delay – seconds to wait before starting to repeat keys

  • repeat_next – time between each repeated key

next_event() → tuple[float, str] | None

Return (remaining, key), or None if no events are pending.

remaining is the number of seconds (float) until the key repeat event should be sent.

press(key: str) → None

Record that key was pressed, disabling repeat if another key is already held down.

release(key: str) → None

Record that key was released, re-enabling repeat once no key is held down.

sent_event() → None

Call this method when a key repeat event was sent.

The timer will be reset for the next event.