Install & Compatibility
Where this runs
tested against v4.0.13 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 0.438s · 27.4MB
glibcpy 3.10–3.95 runs
installs and imports cleanly · install 2.1s · import 0.404s · 28MB
23MB installed
● package 23MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
Text
✓ import urwid
urwid.Text(...)
MainLoop
✓ import urwid
urwid.MainLoop(...)
Button
✓ import urwid
urwid.Button(...)
This quickstart initializes a basic Urwid application displaying text and a button. Clicking the button updates the display with a message, and pressing 'Q' at any point exits the application. It demonstrates key concepts like widgets (Text, Button, Pile, Filler), event handling (connect_signal), and the main event loop (MainLoop).
import urwid
def exit_on_q(key):
if key in ('q', 'Q'):
raise urwid.ExitMainLoop()
def show_message(button):
response = urwid.Text([u"You clicked the button! ", ('bold', u"Press Q to quit.")])
done = urwid.Button(u'Ok')
urwid.connect_signal(done, 'click', exit_program)
top_frame = urwid.Frame(
header=urwid.Text("Message"),
body=urwid.Filler(urwid.Pile([response, done]), 'top'),
footer=None
)
loop.widget = top_frame # Replace current widget with message
def exit_program(button):
raise urwid.ExitMainLoop()
# Create a text widget
text_widget = urwid.Text(u"Hello, Urwid! Press Space to click, Q to quit.")
# Create a button
button = urwid.Button(u'Click me!')
urwid.connect_signal(button, 'click', show_message)
# Arrange widgets in a pile, then fill the screen
pile = urwid.Pile([
urwid.Text("Welcome to Urwid"),
urwid.Divider(),
text_widget,
urwid.AttrMap(button, None, focus_map='reversed') # Add focus highlight
])
filler = urwid.Filler(pile, 'top')
# Create the main loop
loop = urwid.MainLoop(filler, unhandled_input=exit_on_q)
loop.run()
Debug
Known issues
breakingVersion 4.0.0 removed several public and protected methods that were previously deprecated. Examples include `Filler.get_body()`, `Filler.set_body()`, and various methods from `Canvas` and `AttrSpec`.fixReview upgrade notes for `urwid` 4.0.0 and replace calls to removed methods with their non-deprecated equivalents or current API patterns. If possible, update code to use direct attribute access or new helper functions.
affects: 4.0.0+
breakingVersion 3.0.0 removed several legacy widgets and properties, including `FlowWidget`, `BoxWidget`, `FixedWidget`, and the `__super` property. Code relying on these will fail.fixMigrate existing code using these deprecated components to modern `urwid` widget classes and composition patterns. Refer to `urwid` documentation for alternatives.
affects: 3.0.0+
gotchaWindows support for `urwid` is primarily for Windows 10+ and relies on the default console host (conhost). There may be visual quirks, performance issues, or incomplete feature support (e.g., mouse events) compared to Linux/macOS terminals.fixTest `urwid` applications thoroughly on target Windows environments. Consider using WSL2 for a more consistent terminal experience if extensive `urwid` features are required on Windows.
affects: All versions on Windows
gotchaWhile `user_arg` for `urwid.connect_signal` was briefly deprecated (v3.0.4) and then un-deprecated (v3.0.5), it can still lead to confusion. The `user_args` parameter (as a tuple) is generally preferred for passing multiple arguments or for consistency with other callback patterns.fixFor new code, prefer `user_args=(arg1, arg2)` when connecting signals. For existing code, `user_arg` should continue to function in 3.0.5+ but be aware of its history if encountering warnings in older 3.x versions.
affects: 3.0.4, 3.0.5+
gotchaUrwid's main loop typically captures all input, including mouse events and keyboard input. This can make debugging or external interaction with the terminal challenging. Ensure your `unhandled_input` handler or event filtering is robust.fixDesign your `unhandled_input` function carefully to handle unexpected keys or provide an escape mechanism. For debugging, consider redirecting output or using an external debugger that can attach to the process without interfering with `urwid`'s input loop.
affects: All versions
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'urwid'
The urwid library is not installed in the current Python environment.
TypeError: LineBox.__init__() missing 1 required positional argument: 'original_widget'
The urwid.LineBox widget constructor requires another widget to wrap around it as its 'original_widget' argument.
fixurwid.LineBox(urwid.Text("Content inside box")) AttributeError: 'Frame' object has no attribute 'set_body'
The urwid.Frame widget does not have a 'set_body' method; its header, body, and footer widgets are updated by direct attribute assignment.
fixframe_instance.body = new_widget
ValueError: invalid palette entry
An entry in the urwid palette list or dictionary is not correctly formatted, typically missing required elements or having invalid values.
fixEnsure palette tuples follow the format (name, foreground, background, mono, foreground_high, background_high). Example: [('body', 'white', 'black', '', '#fff', '#000')] Upgrade
Version history
4.0.13latest on PyPI · released Aug 25, 2026
Audit
Dependencies
No dependency data recorded yet.