GithubHelp home page GithubHelp logo

urwid / urwid Goto Github PK

View Code? Open in Web Editor NEW
2.7K 2.7K 310.0 9.87 MB

Console user interface library for Python (official repo)

Home Page: urwid.org

License: GNU Lesser General Public License v2.1

Python 98.99% CSS 0.03% JavaScript 0.96% Dockerfile 0.02%

urwid's Introduction

Urwid

current version on PyPi Documentation Status Gitter CI status pre-commit test coverage

About

Urwid is a console user interface library for Python on Linux, OSX, Cygwin or other unix-like OS and partially supports Windows OS (see below).

It includes many features useful for text console application developers including:

  • Applications resize quickly and smoothly
  • Automatic, programmable text alignment and wrapping
  • Simple markup for setting text attributes within blocks of text
  • Powerful list box with programmable content for scrolling all widget types
  • Your choice of event loops: Twisted, Glib, Tornado, asyncio, trio, ZeroMQ or select-based loop
  • Pre-built widgets include edit boxes, buttons, check boxes and radio buttons
  • Display modules include raw, curses, and experimental LCD and web displays
  • Support for UTF-8, simple 8-bit and CJK encodings
  • 24-bit (true color), 256 color, and 88 color mode support
  • Compatible with Python 3.7+ and PyPy
Home Page:

http://urwid.org/

Installation

To install using pip

pip install urwid

For advanced functionality extra requirements need to be installed. Example for ZeroMQ event loop and LCD display:

pip install urwid[serial,zmq]

Alternatively if you are on Debian or Ubuntu

apt-get install python3-urwid

Windows support notes

  • Not supported:
  1. Terminal widget and all related render API (TermCanvas, TermCharset, TermModes, TermScroller)
  2. Any file descriptors except sockets (Windows OS limitation)
  3. ZMQEventLoop.
  • Special requirements:
  1. Extra libraries required for curses display support:
pip install urwid[curses]
  • CursesDisplay incorrectly handles mouse input in case of fast actions.
  • Only UTF-8 mode is supported.

Testing

To run tests locally, install & run tox. You must have appropriate Python versions installed to run tox for each of them.

To test code in all Python versions:

tox                     # Test all versions specified in tox.ini:
tox -e py39             # Test Python 3.9 only
tox -e py39,py10,pypy3  # Test Python 3.9, Python 3.10 & pypy3

Supported Python versions

  • 3.7
  • 3.8
  • 3.9
  • 3.10
  • 3.11
  • 3.12
  • pypy3

Authors

Creator

wardi

Maintainers

and3rson, tonycpsu, ulidtko, penguinolog

Contributors

1in7billion, abadger, agrenott, akorb, alethiophile, aleufroy, alobbs, amjltc295, and-semakin, andrewshadura, andy-z, anttin2020, Apteryks, Arfrever, AutoAwesome, belak, berney, bk2204, BkPHcgQL3V, bwesterb, carlos-jenkins, Certseeds, Chipsterjulien, chrisspen, cltrudeau, Codeberg-AsGithubAlternative-buhtz, cortesi, d0c-s4vage, derdon, dholth, dimays, dlo, dnaeon, doddo, douglas-larocca, drestebon, dsotr, dwf, EdwardBetts, elenril, EnricoBilla, extempore, fabiand, floppym, flowblok, fmoreau, goncalopp, Gordin, GregIngelmo, grzaks, gurupras, HarveyHunt, Hoolean, hukka, hydratim, ids1024, imrek, isovector, itaisod, ixxra, jeblair, johndeaton, jonblack, jspricke, kedder, Kelketek, KennethNielsen, kesipyc, kkrolczyk, Kwpolska, Lahorde, laike9m, larsks, lfam, lgbaldoni, lighth7015, livibetter, Lothiraldan, Mad-ness, madebr, magniff, marlox-ouda, mattymo, mdtrooper, mgk, mimi1vx, mobyte0, MonAaraj, MonthlyPython, mountainstorm, mselee, mwhudson, naquad, nchavez324, neumond, nolash, ntamas, nyov, ocarneiro, okayzed, pquentin, rbanffy, ReddyKilowatt, regebro, renegarcia, rianhunter, roburban, RRMoelker, rwarren, scopatz, seanhussey, seonon, shadedKE, sithglan, Sjc1000, sporkexec, squrky, ssbr, techdragon, thehunmonkgroup, thisch, thornycrackers, TomasTomecek, tompickering, tony, ttanner, tu500, uSpike, vega0, vit1251, waveform80, Wesmania, xandfury, xndcn, zhongshangwu, zrax

urwid's People

Contributors

abadger avatar aglyzov avatar and-semakin avatar and3rson avatar anonymoux47 avatar aszlig avatar danschwarz avatar dependabot[bot] avatar eevee avatar garrison avatar hootnot avatar inducer avatar ivanov avatar julian avatar marienz avatar matthijskooijman avatar mgiusti avatar nocarryr avatar ntamas avatar pazz avatar penguinolog avatar rndusr avatar robla avatar techtonik avatar tonycpsu avatar true-world avatar tu500 avatar ulidtko avatar wackywendell avatar wardi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

urwid's Issues

MonitoredFocusList does not support negative indices

I'm using a Pile which I'm dynamically changing the contents of, I went to remove the last item using a negative index and I get:

IndexError: focus index is out of range: 2

Upon digging into the code, it appears there is no accounting for negative indices in the MonitoredFocusList.__delitem__ call. It looks like the slicing mechanism used in a bunch of places assumes positive indices.

I'm using .pop() as a work around, so this isn't a big deal and it may not be worth fixing. A note in the documentation would be good if this is going to stay as a known issue.

Bidirectional text support

trac ticket https://excess.org/urwid/ticket/14

When someone tries using Urwid with Arabic or Hebrew text it is displayed in the wrong order.

Automatic switching of text order and handling or UTF-8 order-declaring codes would be a very nice thing to have. The structures used by StandardTextLayout should support the addition of this feature, but some changes will likely be necessary for efficient BiDi handling.

Italicizing Text

Urwid allows for making text bold or underlined, but as far as I can tell does not allow for italics. Is it possible to make text italicized in urwid and if not, could it be added in a future version?

I apologize if I'm missing something obvious.

Test failures

Urwid has 2 test failures when Tornado and Twisted are installed.
I use Tornado 3.2 and Twisted 13.2.0.

======================================================================
FAIL: test_run (urwid.tests.test_event_loops.TornadoEventLoopTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/urwid/urwid/tests/test_event_loops.py", line 55, in test_run
    self.assertEqual(out, ["waiting", "hello", "waiting", "clean exit"])
AssertionError: Lists differ: ['waiting', 'hello', 'clean ex... != ['waiting', 'hello', 'waiting'...

First differing element 2:
clean exit
waiting

Second list contains 1 additional elements.
First extra element 3:
clean exit

- ['waiting', 'hello', 'clean exit']
+ ['waiting', 'hello', 'waiting', 'clean exit']
?                      +++++++++++


======================================================================
FAIL: test_run (urwid.tests.test_event_loops.TwistedEventLoopTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/urwid/urwid/tests/test_event_loops.py", line 128, in test_run
    "clean exit"])
AssertionError: Lists differ: [u'da', u'ta', 'waiting', 'hel... != ['da', 'ta', 'waiting', 'hello...

First differing element 4:
clean exit
waiting

- [u'da', u'ta', 'waiting', 'hello', 'clean exit', 'waiting']
+ ['da', 'ta', 'waiting', 'hello', 'waiting', 'clean exit']

----------------------------------------------------------------------
Ran 293 tests in 2.052s

FAILED (failures=2)

ListBox method set_focus_valign always set align to top

When using set_focus_valign('bottom') method, it seem to always set align to top, no matter what align method is used.

Example code:

import urwid


text = """Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est.

Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.

Suspendisse lectus leo, consectetur in tempor sit amet, placerat quis neque. Etiam luctus porttitor lorem, sed suscipit est rutrum non. Curabitur lobortis nisl a enim congue semper. Aenean commodo ultrices imperdiet. Vestibulum ut justo vel sapien venenatis tincidunt. Phasellus eget dolor sit amet ipsum dapibus condimentum vitae quis lectus. Aliquam ut massa in turpis dapibus convallis. Praesent elit lacus, vestibulum at malesuada et, ornare et est. Ut augue nunc, sodales ut euismod non, adipiscing vitae orci. Mauris ut placerat justo. Mauris in ultricies enim. Quisque nec est eleifend nulla ultrices egestas quis ut quam. Donec sollicitudin lectus a mauris pulvinar id aliquam urna cursus. Cras quis ligula sem, vel elementum mi. Phasellus non ullamcorper urna.

Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In euismod ultrices facilisis. Vestibulum porta sapien adipiscing augue congue id pretium lectus molestie. Proin quis dictum nisl. Morbi id quam sapien, sed vestibulum sem. Duis elementum rutrum mauris sed convallis. Proin vestibulum magna mi. Aenean tristique hendrerit magna, ac facilisis nulla hendrerit ut. Sed non tortor sodales quam auctor elementum. Donec hendrerit nunc eget elit pharetra pulvinar. Suspendisse id tempus tortor. Aenean luctus, elit commodo laoreet commodo, justo nisi consequat massa, sed vulputate quam urna quis eros."""


class Ui:
    def __init__(self):
        self.header = urwid.Text('Hello World!')
        self.text = urwid.Text(text)
        layout = [
            urwid.Padding(self.header, left=1, right=1),
            urwid.Divider(),
            urwid.Padding(self.text, left=1, right=1),
        ]
        self.listbox = urwid.ListBox(layout)
        self.statusbar = urwid.Text('statusbar', align='right')
        self.main_frame = urwid.Frame(self.listbox)
        self.main_frame.set_footer(self.statusbar)
        self.mainloop = urwid.MainLoop(self.main_frame, unhandled_input=self.unhandled_input)

    def unhandled_input(self, key):
        if key in ('q', 'Q'):
            raise urwid.ExitMainLoop()
        elif key in 'G':
            self.listbox.set_focus(2)
            self.listbox.set_focus_valign('bottom')

if __name__ == '__main__':
    ui = Ui()
    ui.mainloop.run()

How do you create a tree with multiple top-level nodes?

I'd like to create a tree which has multiple top-level nodes, e.g:

[-] Parent 1
  * Child 1
  * Child 2
[-] Parent 2
  * Child 1
  * Child 2

The documentation is not very detailed in explaining how the TreeListBox and TreeWalker work together to build the tree. The examples browse.py and treesample.py both result in a single top-level node.

Crash when mouse tracking is enabled

Hi,

I'm working on enabling mouse scrolling in mitmproxy's console app. After enabling mouse input, a crash is triggered:

Traceback (most recent call last):
  File "/Users/cortesi/mitmproxy/mitmproxy/libmproxy/console/__init__.py", line 611, in run
    self.ui.run_wrapper(self.loop)
  File "/Library/Python/2.7/site-packages/urwid/display_common.py", line 757, in run_wrapper
    return fn()
  File "/Users/cortesi/mitmproxy/mitmproxy/libmproxy/console/__init__.py", line 825, in loop
    keys = self.ui.get_input()
  File "/Library/Python/2.7/site-packages/urwid/raw_display.py", line 324, in get_input
    keys, raw = self.parse_input(None, None, self.get_available_raw_input())
  File "/Library/Python/2.7/site-packages/urwid/raw_display.py", line 465, in parse_input
    codes, wait_for_more)
  File "/Library/Python/2.7/site-packages/urwid/escape.py", line 383, in process_keyqueue
    if run[0] == "esc" or run[0].find("meta ") >= 0:
AttributeError: 'tuple' object has no attribute 'find'

You can reproduce this as follows:

  • Install the "mouse" branch of mitmproxy
  • Start mitmproxy
  • Press "Escape", and then click anywhere on the screen

This issue does not occur when the set_mouse_tracking call is removed.

I've tested this with iTerm on OSX Yosemite.

Cheers,

Aldo

ValueError: too many values to unpack (expected 1) when using height = ( 'relative', nn ) in Filler objects wrapped in a BoxAdapter

When filling any object wrapped inside a BoxAdapter, I recieve the following error-

ValueError: too many values to unpack (expected 1)

Sample code

import urwid

class Window(urwid.WidgetWrap):
    def __init__(self, caption, menuitems=[]):
        self.caption = urwid.Padding(urwid.Text(caption), left = 1)
        yes = urwid.Text(u"Yes")

        self.widgets = [
            urwid.AttrWrap(self.caption, "Window Title")
        ]

        self.widgets.append(urwid.BoxAdapter(
            urwid.Filler(
                urwid.AttrWrap( urwid.Text(u""), "Window Background" ),
                valign="top",
                height=('relative', 50)
            ), height = 1))


        display_widget = urwid.Pile(self.widgets)
        urwid.WidgetWrap.__init__(self, display_widget)

PALETTE = [
    ( None,                 'light gray',       'black'         ),
    ( 'Window Title',       'yellow',           'dark blue'     ),
    ( "Window Menu Bar",    "black",            "light gray"    ),
    ( "Window Background",  "black",            "dark gray"     ),
    ( "Active Menu",        "white",            "light blue"    ),
    ( "Inactive Menu",      "black",            "light gray"    ),
]

fill = urwid.Filler(Window(u"Hello, world"), 'top')
loop = urwid.MainLoop(fill, PALETTE)
loop.run()

Stack Trace

Traceback (most recent call last):
  File "window.py", line 44, in <module>
    loop.run()
  File "/usr/lib/python3.4/site-packages/urwid/main_loop.py", line 274, in run
    self.screen.run_wrapper(self._run)
  File "/usr/lib/python3.4/site-packages/urwid/raw_display.py", line 268, in run_wrapper
    return fn()
  File "/usr/lib/python3.4/site-packages/urwid/main_loop.py", line 314, in _run
    self.draw_screen()
  File "/usr/lib/python3.4/site-packages/urwid/main_loop.py", line 565, in draw_screen
    canvas = self._topmost_widget.render(self.screen_size, focus=True)
  File "/usr/lib/python3.4/site-packages/urwid/widget.py", line 141, in cached_render
    canv = fn(self, size, focus=focus)
  File "/usr/lib/python3.4/site-packages/urwid/decoration.py", line 816, in render
    canv = self._original_widget.render((maxcol,), focus)
  File "/usr/lib/python3.4/site-packages/urwid/widget.py", line 141, in cached_render
    canv = fn(self, size, focus=focus)
  File "/usr/lib/python3.4/site-packages/urwid/widget.py", line 1750, in render
    canv = get_delegate(self).render(size, focus=focus)
  File "/usr/lib/python3.4/site-packages/urwid/widget.py", line 141, in cached_render
    canv = fn(self, size, focus=focus)
  File "/usr/lib/python3.4/site-packages/urwid/container.py", line 1516, in render
    canv = w.render((maxcol,), focus=focus and item_focus)
  File "/usr/lib/python3.4/site-packages/urwid/widget.py", line 141, in cached_render
    canv = fn(self, size, focus=focus)
  File "/usr/lib/python3.4/site-packages/urwid/decoration.py", line 403, in render
    canv = self._original_widget.render((maxcol, self.height), focus)
  File "/usr/lib/python3.4/site-packages/urwid/widget.py", line 141, in cached_render
    canv = fn(self, size, focus=focus)
  File "/usr/lib/python3.4/site-packages/urwid/decoration.py", line 818, in render
    canv = self._original_widget.render((maxcol,maxrow-top-bottom),focus)
  File "/usr/lib/python3.4/site-packages/urwid/widget.py", line 141, in cached_render
    canv = fn(self, size, focus=focus)
  File "/usr/lib/python3.4/site-packages/urwid/decoration.py", line 225, in render
    canv = self._original_widget.render(size, focus=focus)
  File "/usr/lib/python3.4/site-packages/urwid/widget.py", line 141, in cached_render
    canv = fn(self, size, focus=focus)
  File "/usr/lib/python3.4/site-packages/urwid/widget.py", line 1003, in render
    (maxcol,) = size
ValueError: too many values to unpack (expected 1)

Listbox with horizontal scroll support

This was in the todo list before migration to github.com
Creating the issue so it doesn't get forgotten about.

May also have some code that does this, I need to read it more thoroughly to be sure.

Trouble focusing widgets in a GridFlow

When I create a GridFlow where most of the items are Piles containing a Text and an Edit, but some are just empty Piles, I'm unable to focus a filled Pile when it is alone on a row.

If you run the grid.py file from https://gist.github.com/bk2204/9731198 in a terminal, you will be unable to select the Edit for Cell 4 with the mouse or the cursor keys. Hitting the down key from Cell 2 takes you directly to Cell 6.

I believe this did work in earlier versions.

Error at compilation time in Ubuntu

When I try to install a version greater than 0.9.9.1 in Ubuntu 11.10, always crashes at compilation.

This is the traceback:

running install
Checking .pth file support in /usr/local/lib/python2.7/dist-packages/
/usr/bin/python -E -c pass
TEST PASSED: /usr/local/lib/python2.7/dist-packages/ appears to support .pth files
running bdist_egg
running egg_info
writing urwid.egg-info/PKG-INFO
writing top-level names to urwid.egg-info/top_level.txt
writing dependency_links to urwid.egg-info/dependency_links.txt
reading manifest file 'urwid.egg-info/SOURCES.txt'
writing manifest file 'urwid.egg-info/SOURCES.txt'
installing library code to build/bdist.linux-i686/egg
running install_lib
running build_py
running build_ext
building 'urwid.str_util' extension
gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.7 -c source/str_util.c -o build/temp.linux-i686-2.7/source/str_util.o
source/str_util.c:25:20: fatal error: Python.h: No such file or directory
compilation terminated.
error: command 'gcc' failed with exit status 1

I tried the installation form Pypi and directly from the source with the same result.

Crash defect in raw_display.py line 749

Hi,

I believe I've found a crash bug in raw_display.py on line 749. Resizing the display downwards in width and height results in IndexError in the following code:

for row in r.content():
    y += 1
    if osb and osb[y] == row: # <-- Crash here
        # this row of the screen buffer matches what is
        # currently displayed, so we can skip this line
        sb.append( osb[y] )
        continue

Replacing the if clause logic with y < len(osb) and osb[y] == row seems to fix the issue for me.

Unable to get the tutorial examples works, including "hello world"

I tried many combination between urwid 1.1.1, 1.2.1, python 2.7.6, 3.4.0, ubuntu 14.04, 13.10, installation via Ubuntu Software Center, via PIP, nothing worked, I still have the same output error:

7 [?47h
Traceback (most recent call last):
File "/home/neo/helloworld.py", line 6, in <module>
File "/home/neo/urwid/main_loop.py", line 274, in run
self.screen.run_wrapper(self._run)
File "/home/neo/urwid/raw_display.py", line 267, in run_wrapper
self.start(alternate_buffer)
File "/home/neo/urwid/raw_display.py", line 201, in start
fd = self._term_input_file.fileno()
UnsupportedOperation: fileno

I don't think this is a general issue existing since several years, but I googled everywhere without finding useful explanation.

Unclear behavior of GridFlow

I have the following code:

#/usr/bin/env python3

import urwid

class CmdWidget(urwid.WidgetWrap):
    def __init__(self, name):
        self.name = name
        urwid.WidgetWrap.__init__(self, urwid.AttrMap(urwid.Text(name), 'body', 'focus'))

    def selectable(self):
        return True

    def keypress(self, size, key):
        return key

items = [
    CmdWidget('XXXXXXXXXXXXX %d' % i)
    for i in range(0, 100)
]
maxw = 22
cols = urwid.GridFlow(items, maxw, 1, 0, 'left')

box = urwid.Frame(urwid.Filler(cols, 'top'), urwid.Text('test'))

palette = [
    ('body', '', ''),
    ('focus', 'yellow', '')
]

urwid.MainLoop(box, palette).run()

when I run it GridFlow doesn't scroll. If I replace CmdWidget with urwid.Button scrolling is fine and everything works as expected. What's wrong with this code? CmdWidget is selectable, implements keypress() and has correct sizing. Why doesn't it work?

Weird behaviour when setting Columns.focus_position

This is kinda hard to describe, so I made a demonstration script that should explain everything when you run it: https://gist.github.com/anonymous/e78bb46914c4343ddf2a

Anyway, I have a dictionary that is presented as a list of key/value pairs with editable value fields and fixed key fields. But the user can also add new keys. When this happens, a new line with editable text fields for key and value is created and the focus is positioned (by setting columns.focus_position = 0) on the key field.

The bug: Sometimes everything works as expected and sometimes the focus is instead on the value field of the new line. It seems the only way to reliably get the cursor on the key field is by hitting Pos1 before adding the new line.

I've tested this with urwid 1.2.1 and 1.3.0, both in Python 3.4.2.

Columns widget docs error?

hi, in the docs it says the Columns widget has a parameter
"widget_list" which may also contain tuples such as:
(given_width, widget)
to "make this column given_width screen columns wide, where given_width is an int"

it actually seems that the tuple must be like this:
('fixed',given_width,widget)

is that correct?

(for reference: http://urwid.org/reference/widget.html#columns)

Newlines for each screen.start()/stop() call

First off thanks for the awesome library!

I am seeing a newline in the terminal for each start and stop call I insert and I have no way to get rid of them. Using the edit.py example:

scopatz@ares ~/xo/xo master $ python3 edit.py main_save.py

scopatz@ares ~/xo/xo master $ 

If I insert

self.loop.screen.start()
self.loop.screen.stop()

right before the self.loop.run() call, I get another blank line for each start/stop pair.

Is there some way to get rid of this and preserve my precious vertical space? Looking through the urwid source it wasn't obvious where this is coming from The behaviour is also there in Python 2.

'utf-8' codec can't decode byte 0xc3

error: UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc3 in position 12: unexpected end of data
file: raw_display.py
line 769: you use l.decode('utf-8') but you should use l.decode('utf-8', 'ignore') and solve many bugs like this

Python3.x build fails

I don't know how this has not been fixed, nor why it passed tests but your python3.x build solution is very flawed.
Here is the traceback from a build attempt on a clean Python3.2 (cpython) install:

Traceback (most recent call last):
File "setup.py", line 28, in
from setuptools import setup, Extension # distribute required for Python 3
ImportError: No module named setuptools

Constructing a ListBox with just a list of items uses a PollingListWalker

and PollingListWalker is apparently deprecated. If using ListBox without an explicit ListWalker is supposed to be deprecated, then the error message should say so, instead of only mentioning PollingListWalker, which doesn't explicitly occur in user code that does this. If this use is not deprecated, then perhaps this should be switched to another ListWalker.

Relevant code

UnboundLocalErrors in mouse_event and move_cursor_to_coords

I have seen two very similar cases where I get an UnboundLocalError for the variable w. Unfortunately, all I have is two backtraces, not a testcase, because the behavior appears unexpectedly (perhaps the user is accidentally striking the wrong key or moving the mouse); as a consequence, I'm not sure what the actual set of steps to reproduce is.

However, the good news is that it appears that the problem is just that a variable isn't defined (being an UnboundLocalError) because a loop never runs, so I intend to submit a pull request to define the variable and do something sensible in those cases where the error would otherwise occur.

This is Debian bug #708305 and is present in 1.1.1. I've included the backtraces below.

Traceback (most recent call last):
File "/home/hodgson/bin/newfol", line 1488, in
main(sys.argv[1:])
File "/home/hodgson/bin/newfol", line 1482, in main
start_curses()
File "/home/hodgson/bin/newfol", line 1079, in start_curses
loop.run()
File "/usr/lib/python3/dist-packages/urwid/main_loop.py", line 272, in run
self.screen.run_wrapper(self._run)
File "/usr/lib/python3/dist-packages/urwid/raw_display.py", line 242, in run_wrapper
return fn()
File "/usr/lib/python3/dist-packages/urwid/main_loop.py", line 337, in _run
self.event_loop.run()
File "/usr/lib/python3/dist-packages/urwid/main_loop.py", line 708, in run
self._loop()
File "/usr/lib/python3/dist-packages/urwid/main_loop.py", line 787, in _loop
self._watch_filesfd
File "/usr/lib/python3/dist-packages/urwid/main_loop.py", line 388, in _update
self.process_input(keys)
File "/usr/lib/python3/dist-packages/urwid/main_loop.py", line 485, in process_input
event, button, col, row, focus=True ):
File "/usr/lib/python3/dist-packages/urwid/container.py", line 1144, in mouse_event
event, button, col, row-htrim, focus )
File "/usr/lib/python3/dist-packages/urwid/decoration.py", line 901, in mouse_event
event, button, col, row-top, focus)
File "/usr/lib/python3/dist-packages/urwid/container.py", line 1658, in mouse_event
focus)
File "/usr/lib/python3/dist-packages/urwid/container.py", line 406, in mouse_event
self.__super.mouse_event(size, event, button, col, row, focus)
File "/usr/lib/python3/dist-packages/urwid/container.py", line 1658, in mouse_event
focus)
File "/usr/lib/python3/dist-packages/urwid/decoration.py", line 664, in mouse_event
focus)
File "/usr/lib/python3/dist-packages/urwid/container.py", line 2171, in mouse_event
col - x, row, focus)
File "/usr/lib/python3/dist-packages/urwid/container.py", line 1653, in mouse_event
if not hasattr(w, 'mouse_event'):
UnboundLocalError: local variable 'w' referenced before assignment

Traceback (most recent call last):
File "/home/hodgson/bin/newfol", line 1183, in
main(sys.argv[1:])
File "/home/hodgson/bin/newfol", line 1177, in main
start_curses()
File "/home/hodgson/bin/newfol", line 992, in start_curses
loop.run()
File "/usr/lib/python3/dist-packages/urwid/main_loop.py", line 272, in run
self.screen.run_wrapper(self._run)
File "/usr/lib/python3/dist-packages/urwid/raw_display.py", line 242, in run_wrapper
return fn()
File "/usr/lib/python3/dist-packages/urwid/main_loop.py", line 337, in _run
self.event_loop.run()
File "/usr/lib/python3/dist-packages/urwid/main_loop.py", line 708, in run
self._loop()
File "/usr/lib/python3/dist-packages/urwid/main_loop.py", line 787, in _loop
self._watch_filesfd
File "/usr/lib/python3/dist-packages/urwid/main_loop.py", line 388, in _update
self.process_input(keys)
File "/usr/lib/python3/dist-packages/urwid/main_loop.py", line 485, in process_input
event, button, col, row, focus=True ):
File "/usr/lib/python3/dist-packages/urwid/container.py", line 1144, in mouse_event
event, button, col, row-htrim, focus )
File "/usr/lib/python3/dist-packages/urwid/decoration.py", line 901, in mouse_event
event, button, col, row-top, focus)
File "/usr/lib/python3/dist-packages/urwid/container.py", line 1658, in mouse_event
focus)
File "/usr/lib/python3/dist-packages/urwid/container.py", line 406, in mouse_event
self.__super.mouse_event(size, event, button, col, row, focus)
File "/usr/lib/python3/dist-packages/urwid/container.py", line 1658, in mouse_event
focus)
File "/usr/lib/python3/dist-packages/urwid/decoration.py", line 664, in mouse_event
focus)
File "/usr/lib/python3/dist-packages/urwid/container.py", line 2173, in mouse_event
col - x, row, focus)
File "/usr/lib/python3/dist-packages/urwid/container.py", line 1650, in mouse_event
if w.selectable():
UnboundLocalError: local variable 'w' referenced before assignment

resizing widgets?

hi. How can i manually modify exisiting columns widths?

tutorials doesnt provide such info, and I cant find anything on this topic.

Thanks for help/

watch_file blocks keypress processing

The following urwid program displays the key pressed, or any line that comes in from the Popen'd program:

#!/usr/bin/env python
import urwid
from threading import Thread
from subprocess import Popen, PIPE
import time
import os


class MyText(urwid.Text):
    def __init__(self):
        super(MyText, self).__init__('Press Q to quit', align='center')

    def selectable(self):
        return True

    def keypress(self, size, key):
        if key in ['q', 'Q']:
            raise urwid.ExitMainLoop()
        else:
            self.set_text(repr(key))


class Writer(object):
    def __init__(self):
        self._child = Popen(
                'for i in `seq 5`; do sleep 1; echo $i; done',
                #"ssh localhost 'for i in `seq 5`; do sleep 1; echo $i; done'",
                shell=True, stdout=PIPE, stderr=PIPE)

    def file(self):
        return self._child.stdout

    def fileno(self):
        return self._child.stdout.fileno()

w = Writer()
txt = MyText()
top = urwid.Filler(txt)
mainloop = urwid.MainLoop(top)

def on_writer():
    c = w.file().read(1)
    if c == '': # terminated
        mainloop.remove_watch_file(w.fileno())
        return
    if c == '\n':
        return
    txt.set_text(c)
    mainloop.draw_screen()

mainloop.watch_file(w.fileno(), on_writer)

mainloop.run()

The above program works, but if I change the Popen'd command to the ssh localhost ... version, the program stops displaying keypresses until the ssh localhost ... command finishes. Why is that?

Environment: CentOS 6.6, Python 2.7.4, urwid 1.3.1-dev.

Cannot put a Terminal Widget in a ListBox Widget - Calculated cursor cords None but rendered cursor coords (x, y)

If I create a Terminal widget that I decorate with a BoxAdapter widget and add it to a ListBox widget, when rendering the ListBox widget it throws an exception because the calculated cursor coordinates and the rendered coordinates do not match. The Terminal widget does not implement a get_cursor_coords() method, hence the calculated cursor coordinates are always None.

Python 2.7.5 (default, Mar  9 2014, 22:15:05) 
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import urwid
>>> vterm = urwid.Terminal(None)
>>> box_adapter = urwid.BoxAdapter(vterm, 20)
>>> list_box = urwid.ListBox(urwid.SimpleListWalker([box_adapter]))
>>> list_box.render((80,40))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Python/2.7/site-packages/urwid/widget.py", line 141, in cached_render
    canv = fn(self, size, focus=focus)
  File "/Library/Python/2.7/site-packages/urwid/listbox.py", line 481, in render
    raise ListBoxError, "Focus Widget %r at position %r within listbox calculated cursor coords %r but rendered cursor coords %r!" %(focus_widget,focus_pos,cursor,c_cursor)
urwid.listbox.ListBoxError: Focus Widget <BoxAdapter selectable flow widget <Terminal selectable box widget> height=20> at position 0 within listbox calculated cursor coords None but rendered cursor coords (0, 0)!
>>> urwid.__version__
'1.3.0'

I tried to fix this by implementing a get_cursor_coords() method for urwid.Terminal, using it's term.term_cursor but this didn't work.

def get_cursor_coords(self, size):
     if self.term:
         return self.term.term_cursor

urwid.Terminal.get_cursor_coords = get_cursor_coords

The first time it was called it seemed to return None still, later it would return (10,0) for instance, but ListBox's render would still see it as None. I don't understand enough to work out how to get this to work. I'd like use Terminal widgets to host the output of external commands so that it properly renders the output such as carriage returns. I'd like to have multiple terminals, one for each run of an external program, and I'd like the user to be able to scroll up and down in my Urwid application to see the output of each.

python3 support

I'm confused, since the README states that this project is python3.3+ compatible yet there are many syntax errors...

Traceback (most recent call last):
  File "examples/bigtext.py", line 26, in <module>
    import urwid
  File "urwid-1.2.1/urwid/__init__.py", line 24, in <module>
    from urwid.widget import (FLOW, BOX, FIXED, LEFT, RIGHT, CENTER, TOP, MIDDLE,
  File "urwid-1.2.1/urwid/widget.py", line 24, in <module>
    from urwid.util import (MetaSuper, decompose_tagmarkup, calc_width,
  File "urwid-1.2.1/urwid/util.py", line 48
    except ValueError, e:
                     ^
SyntaxError: invalid syntax

There are many more python3 invalid syntax instances.

consider switching to a urwid org?

using a github org would make it look more official, and be better for the creation of dependent tools e.g. an 'urwid-extras' package etc.

I'd recommend this for after #41 is resolved.

Moving an app into the background and back fails with raw_display

This is the code for a minimal application from the tutorial:

import urwid

txt = urwid.Text(u"Hello World")
fill = urwid.Filler(txt, 'top')
loop = urwid.MainLoop(fill)
loop.run()

When I put this application into the background (via CTRL-Z), the cursor of my console disappears. If I then try to move this application back into the forground with the fg command, the text [1] + continued python minimal.py is printed but the application is not running again (at least one can't see it). With the following code, everything works as expected: the application can be moved into the background without modifying the cursor and can be moved back into the foreground so the user can continue using the application.

import urwid
from urwid import curses_display

txt = urwid.Text(u"Hello World")
fill = urwid.Filler(txt, 'top')
loop = urwid.MainLoop(fill, screen=curses_display.Screen())
loop.run()

wardi from the IRC channel told me to note that there are the signals SIGSTOP, SIGCONT, SIGTSTP, SIGTTIN, and SIGTTOU. Some or maybe all of them may be useful for resolving this issue.

getting UnicodeEncodeError when starting an urwid application with LANG set to an not-installed locale

Hello,

Here's the traceback:

Traceback (most recent call last):
File "bin/app.py", line 153, in
main()
File "bin/app.py", line 149, in main
loop.run()
File "/usr/lib/python3.4/site-packages/urwid/main_loop.py", line 274, in run
self.screen.run_wrapper(self._run)
File "/usr/lib/python3.4/site-packages/urwid/raw_display.py", line 268, in run_wrapper
return fn()
File "/usr/lib/python3.4/site-packages/urwid/main_loop.py", line 314, in _run
self.draw_screen()
File "/usr/lib/python3.4/site-packages/urwid/main_loop.py", line 566, in draw_screen
self.screen.draw_screen(self.screen_size, canvas)
File "/usr/lib/python3.4/site-packages/urwid/raw_display.py", line 770, in draw_screen
self._term_output_file.write(l)
UnicodeEncodeError: 'ascii' codec can't encode character '\u250c' in position 0: ordinal not in range(128)

Additionnal information:

urwid.set_encoding("utf8") is called before running the loop.

Appliction is started like this: "LANG=aa_DJ.UTF-8 python app.py" where aa_DJ locale is not installed.

High CPU load with AsyncioEventLoop

My project's CPU load is between 8 and 9 % when it's doing absolutely nothing. I've found that setting AsyncioEventLoop._idle_emulation_delay from 1/256 to something like 1/20 reduces CPU load to around 1 %, and I don't notice any reduced responsiveness.

Also, AsyncioEventLoop._we_started_event_loop isn't used anywhere, so it can be removed?

Continuous Integration and running the tests

Hi @wardi

I started using Travis-CI for testing my fork of urwid. As you can see, there are some failures in several Python versions: 2.4, 2.5, 3.2 and 3.3.

Is python setup.py test the preferred way to run the tests? What do you think about having the upstream urwid repository in CI? It's free for open source and it can automatically run the tests in all Python versions for every incoming pull request and also triggers a build every time you update master.

I'll be happy to provide a patch for having urwid in CI, but I believe that you, as the owner of the repository, have to sign in Travis' website and turn no the automatic builds for urwid.

BarGraph with multiple hlines raises WidgetError

Trying to use hlines in a BarGraph, I get this error everytime I try to
display more than one horizontal line:

urwid.widget.WidgetError: Widget rendered (116 x 95) canvas when passed size (116, 75)!

Python script to reproduce:

import urwid

palette = [
     ('normal', 'dark blue', 'dark gray'),
     ('inverse', 'dark gray', 'dark blue'),
]

def main():
     graph = urwid.BarGraph(
         ['normal', 'inverse'],
         ['normal', 'inverse'],
         { (1,0): 'normal', },
     )
     bardata = [(1,), (2,), (4,), (8,), (16,), (32,)]
     lines = [10]
     graph.set_data(bardata, 40, lines)
     loop = urwid.MainLoop(graph, palette)
     loop.run()

if __name__ == "__main__":
     main = main()

This works and it shows a line, but when I try to add more lines, e.g.: lines = [10, 20] or: lines = [1,2,5,10], then the WidgetError mentioned above is raised.

If I am using hlines the wrong way, I'd like to know what I am doing wrong. But I was told BarGaph should not raise a WidgetError like this anyway. Hence this bug report.

I reproduced this on:

  • python 3.4 + urwid 1.2.1 in a virtualenv
  • python 2.7.5 + urwid 1.1.1 as shipped by ubuntu 13.10.

Best regards,
Heiko Noordhof

MainLoop.watch_file() on a named pipe always selects after the first write

Writing to a named pipe being watched with MainLoop.watch_file() will cause the callback to be called indefinitely afterwards; even if there is no data to be read.

Repro:

import urwid
import os
import os.path

class Example:
    def __init__(self):
        self.view = urwid.Text("it should count the number of writes to /tmp/urwid here")
        self.iteration = 0

    def main(self):
        self.loop = urwid.MainLoop(
            urwid.Filler(self.view, 'bottom'),
            [],
            unhandled_input = self.controls
        )

        pipename = "/tmp/urwid"
        if os.path.exists(pipename):
            os.remove(pipename)
        os.mkfifo(pipename)

        # can't use open() because it is blocking, and never makes it to run()
        self.pipe = os.open(pipename, os.O_RDONLY|os.O_NONBLOCK)
        self.loop.watch_file(self.pipe, self.handle_pipe)

        self.loop.run()

    def handle_pipe(self):
        # read everything in the pipe
        os.read(self.pipe, 1024)
        self.iteration += 1
        self.view.set_text(str(self.iteration))
        self.loop.draw_screen()

    def controls(self, key):
        raise urwid.ExitMainLoop()

Example().main()

Test with:

$ echo > /tmp/urwid

Expected result:
The text widget should change to say "1"

Actual result:
The text widget counts indefinitely.

SIGINT is not reset correctly

I wrote a program which first uses an urwid UI to get some information, and then drops down to normal print()s to display some stuff, however I discovered that Ctrl-C stops working after the urwid UI is closed.

import signal
import time
import urwid

def quit(_):
    raise urwid.ExitMainLoop

def run_chooser():
    button = urwid.Button('quit')
    urwid.connect_signal(button, 'click', quit)

    root = urwid.Filler(button, 'top')

    mainloop = urwid.MainLoop(
        root,
        event_loop=urwid.GLibEventLoop(),
    )
    mainloop.run()

def main():
    run_chooser()
#    signal.signal(signal.SIGINT, signal.default_int_handler)

    print('Now press Ctrl-C:')
    while True:
        time.sleep(10)
        # pressing Ctrl-C should get a KeyboardInterrupt...
        print('sleep finished')

if __name__ == '__main__':
    main()

Expected behaviour:
Pressing Ctrl-C at the prompt raises a KeyboardInterrupt.
(comment out the run_chooser() call to reproduce)

Actual behaviour: time.sleep() returns (expected, given the C sleep() function returns when it receives a not-ignored signal) but doesn't raise a KeyboardInterrupt (presumably because it doesn't invoke signal.default_int_handler, but I have no idea why that is)

The commented out signal.signal line is the workaround for the issue: entertainingly, signal.getsignal(signal.SIGINT) is signal.default_int_handler before using that workaround, so there's something which is breaking the signal below Python's signal module.

Overlay on terminal widget

It seems that the terminal widget does not support an overlay/pop up unless said overlay covers more 100% or more of the width of the terminal widget.

I used examples/pop_up.py and replaced the single Button instance in ThingWithAPopUp with urwid.Terminal(None).

class ThingWithAPopUp(urwid.PopUpLauncher):
    def __init__(self):
        self.__super.__init__(urwid.Terminal(None))

Then, the rest is modified from examples/terminal.py

def main():
    top = ThingWithAPopUp()

    def quit(*args, **kwargs):
        raise urwid.ExitMainLoop()

    def handle_key(keys, raw):
        for key in keys:
            if key in ('q', 'Q'):
                quit()
            if key in ('p'):
                top.open_pop_up()

        return keys

    loop = urwid.MainLoop(
        top,
        [('popbg', 'white', 'dark blue')],
        handle_mouse=False,
        input_filter=handle_key,
        pop_ups=True)

    top.original_widget.main_loop = loop
    loop.run()

if __name__ == '__main__':
    main()

It seems like the area of the pop up is shifted to the right until the end of the terminal widget. This is more visible if you wrap the terminal widget with a urwid.Padding widget.

urwid LICENSE

@wardi:

Is there any reason for the LGPL license on urwid? Would you consider changing it to a permissive license like MIT or BSD if there was a good reason?

Use terminfo to get terminal capabilities and escape sequences

[renamed issue as problem below has been worked around for now] -wardi

When I run Urwid's examples/browse.py within tmux 1.8, the screen looks like this:

tmux-broken

As you can see, the trailing ends of each line have the underlying (yellow-ish) terminal color showing through.

I use urwid 1.1.1. As you can see in the config below, my $TERM is set to screen-256color. Both gnome-terminal and konsole as outer terminals show this behavior.

The same program within GNU screen is fine:

screen-ok

Here's my .tmux.conf:

set -g prefix C-a
setw -g mode-keys vi
setw -g aggressive-resize on
set -g status-keys vi
set -g default-terminal "screen-256color"
set -g update-environment "DISPLAY WINDOWID SSH_ASKPASS SSH_AUTH_SOCK SSH_AGENT_PID SSH_CONNECTION XAUTHORITY XDG_SESSION_COOKIE DBUS_SESSION_BUS_ADDRESS SESSION_MANAGER"

set -g alternate-screen on

unbind C-b
bind a send-prefix
unbind h
unbind l
bind h select-window -t :-1
bind l select-window -t :+1
bind C-a last-window

set -g status-bg black
set -g status-fg white
set -g history-limit 10000
setw -g window-status-bg black
setw -g window-status-fg white
setw -g window-status-current-bg colour240
setw -g window-status-current-fg white
setw -g window-status-current-attr bold

I'm not exactly sure whose fault this is--could be urwid, tmux, or something else entirely. Any help would be much appreciated.

Focus all widgets in Columns

In a ListBox/SimpleFocusListWalker setup of Columns widgets, I'd like to have the whole line focused, not just a single widget in Columns. The only way that I can see is to make a new class that derives from Columns and change the render function. I've tried this and only had to change one line.

Should this be an option when initializing Columns objects? Something like this?

urwid.Columns([widget1, widget2, widget3], focus_line=True)

Is there another way to achieve this that I'm missing?

factor out 2to3

2to3 in urwid is causing me pain, here: https://bitbucket.org/ned/coveragepy/issue/347/coverage-pypy3-2to3-is-unacceptably-slow

Since 2to3 was invented, it's become a relatively simple matter to support both py2 and py3 with a single code base. Would you open to a patch that adds the six library as a dependency and factors out 2to3?

I've also had success with the future library, which makes your code base essentially python3 with some noop imports at the top, at the expense of some slight runtime under python2.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.