Martin Siebel | 9 Feb 11:55
Picon
Favicon
Gravatar

ListBox loses focus

Hello,

I am trying to build a GridBox widget, which is similiar to the GridFlow widget, but can be scrolled.

In doing so, I encountered a problem using urwid's ListBox when setting a focus explicitely.
The following code generates a display with 3x5 checkboxes. The focus is explicitely set on the second entry in the third row.
When running this code in a terminal which is large enough to hold the focus without scrolling the list, the focus is set to the first entry in the third row instead of the second.
When the terminal is small enough not to hold the focus without scrolling, the focus is set properly.

I could trace the problem back to the render method of the ListBox, which explicitely alters the focus of the contained Columns object.
(See the second code snippet and the corresponding output).
Is this a bug in the ListBox or am I doing something wrong when setting the focus?

Any help would be appreciated!
Best regards.

Snippet 1:
######################################################################################
#! /usr/bin/python                                                                                                                                                              &nb sp;                   
import urwid
import random

palette = [('header', 'white', 'dark red', "", "#afd", "#f0f"),
           ('footer', 'black', 'light blue', "", "#6f0", "#d00"),
           ('reveal focus', 'dark green', 'yellow', "", "#fd0", "#808"),
           ('body', 'yellow', 'dark green', 'standout', "#808", "#fd0"),
           ('edit', 'black', 'light gray', "", "#f0f", "#afd")]

buttons = [urwid.AttrMap(urwid.CheckBox(k), None, 'reveal focus')
           for k in ["%d %s" % (i, j)
                     for i, j in
                     enumerate(sorted(["".join([chr(random.randint(97, 122))
                                                for x in range(
                                                       random.randint(4, 16))])
                                       for j in range(15)]))]]
body = urwid.ListBox(urwid.SimpleListWalker([urwid.Columns(buttons[3*i:3*i+3])
                                             for i in range(len(buttons)/3)]))
body.set_focus(2)
body.get_focus()[0].set_focus(1)
loop = urwid.MainLoop(body, palette)
loop.screen.set_terminal_properties(colors=256)
loop.run()

Snippet 2:
########################################################################
#! /usr/bin/python                                                                                                                                                              &nb sp;                   
import urwid
import random
import sys
from math import log10
palette = [('header', 'white', 'dark red', "", "#afd", "#f0f"),
           ('footer', 'black', 'light blue', "", "#6f0", "#d00"),
           ('reveal focus', 'dark green', 'yellow', "", "#fd0", "#808"),
           ('body', 'yellow', 'dark green', 'standout', "#808", "#fd0"),
           ('edit', 'black', 'light gray', "", "#f0f", "#afd")]

def log(txt):
    import time
    f = open("/tmp/gridbox.log", "a")
    f.write("%s: %s\n" % (time.strftime("%H:%M:%S"), txt))
    f.close()

class MyListBox(urwid.ListBox):
    def __init__(self, *args, **kwargs):
        urwid.ListBox.__init__(self, *args, **kwargs)
    def render(self, *args, **kwargs):
        log("BEFORE RENDER:")
        for i in self.body:
            l = [j.original_widget for j in i.widget_list]
            log("row %d: [%s], focus is on %d" % (id(i),
                                                  ", ".join([str(id(j)) for j in l]),
                                                  i.get_focus_column()))

        retval = super(MyListBox, self).render(*args, **kwargs)
        log("AFTER RENDER:")
        for i in self.body:
            l = [j.base_widget for j in i.widget_list]
            log("row %d: [%s], focus is on %d" % (id(i),
                                                  ", ".join([str(id(j)) for j in l]),
                                                  i.get_focus_column()))

        return retval

buttons = [urwid.AttrMap(urwid.CheckBox(k), None, 'reveal focus')
           for k in ["%d %s" % (i, j)
                     for i, j in
                     enumerate(sorted(["".join([chr(random.randint(97, 122))
                                                for x in range(random.randint(4, 16))])
                                       for j in range(15)]))]]
body = MyListBox(urwid.SimpleListWalker([urwid.Columns(buttons[3*i:3*i+3])
                                         for i in range(len(buttons)/3)]))
body.set_focus(2)
body.get_focus()[0].set_focus(1)
loop = urwid.MainLoop(body, palette)
loop.screen.set_terminal_properties(colors=256)
loop.run()

Output of snippet 2:
11:51:44: BEFORE RENDER:
11:51:44: row 35364944: [35360976, 35361296, 35361552], focus is on 0
11:51:44: row 35365008: [35361808, 35362064, 35362320], focus is on 0
11:51:44: row 35365072: [35362576, 35362832, 35363088], focus is on 1
11:51:44: row 35365136: [35363344, 35363600, 35363856], focus is on 0
11:51:44: row 35365200: [35364112, 35364368, 35364624], focus is on 0
11:51:44: AFTER RENDER:
11:51:44: row 35364944: [35360976, 35361296, 35361552], focus is on 0
11:51:44: row 35365008: [35361808, 35362064, 35362320], focus is on 0
11:51:44: row 35365072: [35362576, 35362832, 35363088], focus is on 0
11:51:44: row 35365136: [35363344, 35363600, 35363856], focus is on 0
11:51:44: row 35365200: [35364112, 35364368, 35364624], focus is on 0



_______________________________________________
Urwid mailing list
Urwid <at> lists.excess.org
http://lists.excess.org/mailman/listinfo/urwid
Marco Giusti | 18 Jan 22:14
X-Face
Picon
Gravatar

an idea about dialogs

attached an idea that comes to me about dialogs, but sadly it does not
work, may you can help me to investigate why. what is nice about this
idea is that a dialog freeze the normal program execution the following
logic could be implemented:

	dialog = YesNoDialog()
	ret = dialog.run()
	if ret = 'yes':
		...
	elif ret == 'no':
		...
Attachment (2loops.py): text/x-python, 803 bytes
_______________________________________________
Urwid mailing list
Urwid <at> lists.excess.org
http://lists.excess.org/mailman/listinfo/urwid
Ian Ward | 11 Dec 21:33
Favicon
Gravatar

Re: [bugreport] container.py

Patrick Totzke wrote on 2011-12-11 15:18:
> Quoting Ian Ward (2011-12-11 20:12:54)
>> Patrick Totzke wrote on 2011-12-11 15:06:
>>> Quoting Ian Ward (2011-12-11 19:58:40)
>>>> Patrick Totzke wrote on 2011-12-11 14:48:
>>>>> Hi, I just got an uncaught UnboundLocalError from container.py:
>>>>> best,
>>>>> /p
>>>>
>>>> Interesting.
>>>>
>>>> So it looks like you have a Pile that contains no widgets, and yet
>>>> move_cursor_to_coords is still being called on it, like it's about to
>>>> take the focus.  I guess that could happen if your ListBox has no
>>>> selectable widgets in it, but I'm wondering if there will be other
>>>> problems with having a 0-height focus widget.
>>> not that i'm aware of. i'll check this.
>>>
>>>> try adding:
>>>>
>>>>    else: return False
>>>>
>>>> after the for loop, container.py line 1001.  And let me know if things
>>>> continue on any further for you.
>>> I tried the changes like the patch below suggests,
>>> but the problem still exists.
>>
>> Sorry, this is what I meant:
>>
>> --- a/urwid/container.py        Tue Nov 29 00:31:45 2011 -0500
>> +++ b/urwid/container.py        Sun Dec 11 15:12:11 2011 -0500
>> @@ -998,6 +998,8 @@
>>             if wrow+r > row:
>>                 break
>>             wrow += r
>> +        else:
>> +            return False
>>
>>         if not w.selectable():
>>             return False
> 
> This gives the following trace for me.
> thx,
> /p

An empty Pile in a ListBox seems to be a rich veign of bugs.  It's the
sort of thing that's easy to make tests for, though.  Do you have a
minimal example that causes this for you?

In my first try I made ListBox die too, but in a different way:

urwid.MainLoop(urwid.ListBox(urwid.SimpleListWalker([urwid.Pile([])]))).run()

I'll start writing some tests.

Ian
Ian Ward | 11 Dec 21:11
Favicon
Gravatar

Changing Padding(width) default value in 1.1

In 0.9.9 after adding the more user-friendly parameters left and right
to the Padding constructor, I also quietly gave the align and width
parameters default values of 'left' and 'pack'.

The latter has now caused problems for a number of people.  A really
common request is to just want to indent something by a few characters,
but to do that safely you need to do something like:

    urwid.Padding(my_thing, width=('relative', 100), left=4)

My preference is to change the width default to ('relative', 100) for
the next Urwid release, and add a warning for people using Padding
without specifying a width in the next bugfix release 1.0.2.

The 'pack' option only really works for Text widgets, and only makes a
difference to the appearance (as compared to ('relative', 100) when the
text alignment is different than than the padding alignment).  So I
believe the potential for breaking existing programs is low.

If this change will cause problems for you please speak up, maybe there
is some other option that won't break otherwise working code built for
0.9.9/1.0

Ian
Patrick Totzke | 11 Dec 20:48

[bugreport] container.py

Hi, I just got an uncaught UnboundLocalError from container.py:
best,
/p

Traceback (most recent call last):
  File "/usr/local/bin/alot", line 20, in <module>
    main()
  File "/usr/local/lib/python2.7/dist-packages/alot/init.py", line 101, in main
    args.colours,
  File "/usr/local/lib/python2.7/dist-packages/alot/ui.py", line 111, in __init__
    self.mainloop.run()
  File
"/usr/local/lib/python2.7/dist-packages/urwid-1.0.0-py2.7-linux-x86_64.egg/urwid/main_loop.py",
line 274, in run
    self.screen.run_wrapper(self._run)
  File
"/usr/local/lib/python2.7/dist-packages/urwid-1.0.0-py2.7-linux-x86_64.egg/urwid/raw_display.py",
line 229, in run_wrapper
    return fn()
  File
"/usr/local/lib/python2.7/dist-packages/urwid-1.0.0-py2.7-linux-x86_64.egg/urwid/main_loop.py",
line 307, in _run
    self.event_loop.run()
  File
"/usr/local/lib/python2.7/dist-packages/urwid-1.0.0-py2.7-linux-x86_64.egg/urwid/main_loop.py",
line 1159, in wrapper
    rval = f(*args,**kargs)
  File
"/usr/local/lib/python2.7/dist-packages/urwid-1.0.0-py2.7-linux-x86_64.egg/urwid/main_loop.py",
line 358, in _update
    self.process_input(keys)
  File
"/usr/local/lib/python2.7/dist-packages/urwid-1.0.0-py2.7-linux-x86_64.egg/urwid/main_loop.py",
line 447, in process_input
    k = self._topmost_widget.keypress(self.screen_size, k)
  File "/usr/local/lib/python2.7/dist-packages/alot/ui.py", line 56, in keypress
    return self._w.keypress(size, key)
  File
"/usr/local/lib/python2.7/dist-packages/urwid-1.0.0-py2.7-linux-x86_64.egg/urwid/container.py",
line 641, in keypress
    return self.body.keypress( (maxcol, remaining), key )
  File "/usr/local/lib/python2.7/dist-packages/alot/buffers.py", line 32, in keypress
    return self.body.keypress(size, key)
  File
"/usr/local/lib/python2.7/dist-packages/urwid-1.0.0-py2.7-linux-x86_64.egg/urwid/listbox.py",
line 767, in keypress
    return self._keypress_up((maxcol, maxrow))
  File
"/usr/local/lib/python2.7/dist-packages/urwid-1.0.0-py2.7-linux-x86_64.egg/urwid/listbox.py",
line 829, in _keypress_up
    row_offset, 'below')
  File
"/usr/local/lib/python2.7/dist-packages/urwid-1.0.0-py2.7-linux-x86_64.egg/urwid/listbox.py",
line 691, in change_focus
    if target.move_cursor_to_coords((maxcol,),pref_col,row):
  File
"/usr/local/lib/python2.7/dist-packages/urwid-1.0.0-py2.7-linux-x86_64.egg/urwid/container.py",
line 1002, in move_cursor_to_coords
    if not w.selectable():
UnboundLocalError: local variable 'w' referenced before assignment
Marco Giusti | 11 Dec 19:03
Picon
Gravatar

convertion of urwid documentation to sphinx

hi! i'm in the process of convert the urwid documentation (the tutorial,
the manual and the reference doc) to sphinx. here[1] you can follow the
process, any comments about it is welcome as like or dislike as well.

m.

[1] https://bitbucket.org/gm/urwid/changesets/tip/branch(%22feature-sphinx%22)
Ian Ward | 9 Dec 03:27
Favicon
Gravatar

NicO's Sphere articles on Urwid

I just noticed a 6-article series on Urwid starting here:
http://www.nicosphere.net/urwid-for-python-a-ncurses-library-2541/

It's nice to have coverage like this.  Thanks Nico!

Ian
Ian Ward | 9 Dec 02:43
Favicon
Gravatar

ANN: Speedometer 2.4 - bandwidth and download monitor

Announcing Speedometer 2.8
--------------------------

Speedometer home page:
  http://excess.org/speedometer/

Download:
  http://excess.org/speedometer/speedometer-2.8.tar.gz

New in this release:
====================

 - Added a linear scale option: -l.  Best used in combination with
   -m (and possibly -n) to customize the range to be displayed.
   Thanks to jukie.net for sponsoring this feature.

 - Replace silly "curved" reading with a weighted moving average

 - New option to display all values in bits per second: -s

 - New options to set minimum (-n) and maximum (-m) values
   displayed on the graphs in bytes/s.
   Defaults are -n 32 and -m 2**32

 - Accept shortened versions of -rx and -tx: -r and -t
   My intent is to drop use of the original forms in 3.0 and add
   --long-versions of all options

 - Use IEC notation of sizes MiB, GiB etc.

 - Install script as both speedometer.py and speedometer

About Speedometer
=================

Speedometer is a console bandwidth and file download progress monitor
with a linear/logarithmic bandwidth display and a simple command-line
interface.

Speedometer requires Urwid for full-console bar graph display.  Urwid
may be downloaded from: http://excess.org/urwid/

Speedometer is released under the GNU LGPL.
Ian Ward | 1 Dec 20:05
Favicon
Gravatar

ANN: Urwid 1.0.1, Urwid 0.9.9.3 - Console UI Library

Announcing Urwid 1.0.1 and Urwid 0.9.9.3
----------------------------------------

Urwid home page:
  http://excess.org/urwid/

Manual:
  http://excess.org/urwid/wiki/UrwidManual

Tarballs:
  http://excess.org/urwid/urwid-1.0.1.tar.gz
  http://excess.org/urwid/urwid-0.9.9.3.tar.gz

About these releases:
=====================

These are bug-fix releases for Urwid 1.0.0 and Urwid 0.9.9.2.

Release 0.9.9.3 may be the last in the 0.9.9 series.  Users are strongly
encouraged to upgrade to the 1.0 series.

New in 1.0.1:
=============

  * Fix for Terminal widget in BSD/OSX

  * Fix for a Filler mouse_event() position bug

  * Fix support for mouse positions up to x=255, y=255

  * Fixes for a number of string encoding issues under Python 3

  * Fix for a LineBox border __init__() parameters

  * Fix input input of UTF-8 in tour.py example by converting captions
    to unicode

  * Fix tutorial examples' use of TextCanvas and switch to using
    unicode literals

  * Prevent raw_display from calling tcseattr() or tcgetattr() on
    non-ttys

  * Disable curses_display external event loop support: screen resizing
    and gpm events are not properly supported

  * Mark PollingListWalker as deprecated

New in 0.9.9.3:
===============

  * ListBox now includes a get_cursor_coords() method, allowing
    nested ListBox widgets

  * Fix for a Filler mouse_event() position bug

  * Fix support for mouse positions up to x=255, y=255

  * Fix for leaks of None object in str_util extension

  * Fix for WidgetWrap and AttrMap not working with fixed widgets

About Urwid
===========

Urwid is a console UI library for Python. It features fluid interface
resizing, Unicode support, multiple text layouts, simple attribute
markup, powerful scrolling list boxes and flexible interface design.

Urwid is released under the GNU LGPL.
the grugq | 27 Nov 01:46
Picon

vterm.Terminal patches to enable easier subclassing

Hey,

I've been working on an Urwid application that uses the vterm.Terminal widget 
and integrates properly with Twisted. I've already submitted some minor patches 
to make the raw_display.Screen() object more friendly to subclassing, now I'd 
like to get the Terminal() patched as well. 

The issue is that Terminal assumes the self.master attribute is a file 
descriptor and it will inline calls to os.read()/os.write() on this attribute. 
If the attribute is anything other than a file descriptor, it will raise an 
exception and die. This makes it convoluted to have the master attribute as a 
ProcessProtocol, which is the simplest solution for a Twisted application 
subclassing and implementing the Terminal.

The best solution, from my POV, is to have all access to the the self.master 
attribute wrapped in method calls which can be overwritten. There are two 
options, either make the Terminal widget know how to do I/O on self.master, or 
make self.master an object. That is, either:

# original code:
  os.write(self.master, buf)

# terminal knows too much, code:
  self.write_master(buf)

# I can't believe master's a file(), code:
  self.master.write(buf)

In the attached patch I've implemented the latter approach. I promote the master 
to a file() object (with disabled buffering and non-blocking enabled, so it 
doesn't interfere with Twisted).

As the Gmane.org interface doesn't seem to allow for attachments, I've included 
a pastebin. Ian has the full patch as well, if he wants to forward it to the 
list.

http://pastebin.com/Q6U3Yumi

I'd like to see a solution where it is possible to use, for example, the key 
code parsing code of Terminal without having to cut and paste. 
Terminal.keypress() has only a single line which causes problems with twisted, 
but due to that line my subclass ends up with cut&paste of the whole method. 
This is brittle and non-optimal. Lets make it simpler and cleaner.

cheers,

--gq
Yassen Damyanov | 24 Nov 18:12
Picon
Favicon

Lots of progress bars (help pls)

Hello Ian and community!

I'm new to urwid; trying to compose an application that needs to show lots (LOTS!) of progress bars at the
same time. Could be some 10 to 20, of them, depending on external factors.

I've been digging into urwid for a couple of days already but with a limited success. So I decided to ask for
some help:

(1) Would anyone suggest a widget class (or configuration of classes) that would let progress bars order
themselves let's say 5 or 6 per row (all should be the same width). (A snippet of code would be highly appreciated.)

(2) I would like that composite to have a border built using pseudo-graphical characters on a utf-8
console. Any suggestions for a suitable decorator (or how to build one) ?

Thank you in advance!
Yassen

Gmane