Discussion:
[Urwid] Text box larger than screen, showing only bottom half?
Aleksandr Miroslav
2013-09-01 01:22:21 UTC
Permalink
This is perhaps a silly question, local/but I didn't see how to do it
in the manual.

Given the following code:

num = 100
numbers = [str(i) for i in xrange(num) ]
numbers = "\n".join(numbers)

t = urwid.Text(numbers)
f = urwid.Filler(t)

loop = urwid.MainLoop(f)
loop.run()

If I run the above on a 80x24 terminal (that is, 80 columns, 24 lines)
and num < 24, we are good.

If num is > 24 or any size greater than the number of rows, the text
will be clipped.

Now here is the behavior I am after, I want to display the bottom half
of the text, not the top half. For the above code, this is what I see:

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

That's the top portion of text box, fitted within the contents of the
screen, but I want to display something like this:

76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99

What is the canonical way to do this? I understand of course that I
can calculate the number of rows and then clip the text myself. I
wanted to see if there was some parameter to Text/Fill that would do
this for me?

Thank you.
Aleksandr Miroslav
2013-09-02 21:45:52 UTC
Permalink
On Sat, Aug 31, 2013 at 9:22 PM, Aleksandr Miroslav
Post by Aleksandr Miroslav
Now here is the behavior I am after, I want to display the bottom half
of the text, not the top half.
Using a Pile exhibits the same behavior:


num = 55
numbers = [str(i) for i in xrange(num) ]
numbers_t = [urwid.Text(i) for i in numbers]
numbers_t.reverse()
p = urwid.Pile(numbers_t)

f = urwid.Filler(p,valign='bottom')
loop = urwid.MainLoop(f)
loop.run()

If the height of the pile is less than the height of the screen, but
if the pile is larger, only the top of the pile is displayed. Looking
through the docs, I don't see a way to do this, so I'm guessing that I
would have to ask my filler to see how many rows are available to me
and then only show that many rows?
Aleksandr Miroslav
2013-09-12 00:07:28 UTC
Permalink
On Mon, Sep 2, 2013 at 5:45 PM, Aleksandr Miroslav
Post by Aleksandr Miroslav
Now here is the behavior I am after, I want to display the bottom half
of the text, not the top half.
Taking another look at this, it seems like the only correct way to do
this is to use a ListBox and have the ListWalker disable any input
handling and always set the focus to the last item.

I'll try and whip up a simple example.

Alex
Ian Ward
2013-09-12 00:14:09 UTC
Permalink
On Wed, Sep 11, 2013 at 8:07 PM, Aleksandr Miroslav
Post by Aleksandr Miroslav
On Mon, Sep 2, 2013 at 5:45 PM, Aleksandr Miroslav
Post by Aleksandr Miroslav
Now here is the behavior I am after, I want to display the bottom half
of the text, not the top half.
Taking another look at this, it seems like the only correct way to do
this is to use a ListBox and have the ListWalker disable any input
handling and always set the focus to the last item.
I'll try and whip up a simple example.
Alex
Hi Alex,

Sorry I didn't see your earlier posts (spam filtering problem on my
end) but you're right, the best thing to do is have separate Text
widgets and use a ListBox.

While what you were trying should work, and is likely a bug, having a
huge text widget is really bad for performance because the whole thing
needs to be rendered even if most of it is off the screen.

Ian
Aleksandr Miroslav
2013-09-12 06:33:40 UTC
Permalink
Post by Ian Ward
Sorry I didn't see your earlier posts (spam filtering problem on my
end) but you're right, the best thing to do is have separate Text
widgets and use a ListBox.
Awesome, now that you pointed me in the right direction, I was able to
get the exact behavior I wanted:

import urwid

number_list = [urwid.Text(str(i)) for i in xrange(300) ]
number_list.reverse()

stackwalker= urwid.SimpleListWalker(number_list)
stackwalker.set_focus(len(number_list) -1)
stack = urwid.ListBox(stackwalker)

loop = urwid.MainLoop(stack).run()

I will add some code to my app to disable scrolling, but this is is
pretty much what I wanted.

Thanks!

Loading...