[Urwid] urwid_simple.py problem
James Mills
prologic at shortcircuit.net.au
Sat Jun 3 01:14:51 EDT 2006
Hi,
The "urwid_simple.py" that was posted to this list a while
ago (see attached) I'm having problems with.
I know it's taken me a while :) (lack of time), however I
believe my terminal is translating keycodes for ALT or META
to something else. If I chuck a print keys I get:
['\xf0'] when I press ALT + F for instance, instead of
what urwid_simple is looking for "meta f" in keys.
Comments ?
cheers
James
--
--
-"Problems are Solved by Method"
-
- James Mills <prologic at shortcircuit.net.au>
- HomePage: http://shortcircuit.net.au/~prologic/
- Phone: +61732166379
- Mobile: +61404270962
- Skype: therealprologic
- MSN: prologic at shortcircuit.net.au
- ICQ: 98888663
- IRC: irc://shortcircuit.net.au#se
Please avoid sending me Word or PowerPoint attachments.
See http://www.gnu.org/philosophy/no-word-attachments.html
-------------- next part --------------
#! /usr/bin/env python
"""
Author: Rebecca breu
rebecca at rbreu.de
"""
import urwid.curses_display;
import urwid;
import sys;
######################################################################
class SelText(urwid.Text):
"""
A selectable text widget. See urwid.Text.
"""
def selectable(self):
return True;
def keypress(self, size, key):
"""
Don't handle any keys.
"""
return key;
######################################################################
class Menu(urwid.WidgetWrap):
"""
Creates a popup menu on top of another BoxWidget.
Attributes:
selected -- Contains the item the user has selected by pressing <RETURN>,
or None if nothing has been selected.
"""
selected = None;
def __init__(self, menu_list, attr, pos, body):
"""
menu_list -- a list of strings with the menu entries
attr -- a tuple (background, active_item) of attributes
pos -- a tuple (x, y), position of the menu widget
body -- widget displayed beneath the message widget
"""
content = [urwid.AttrWrap(SelText(" " + w), None, attr[1])
for w in menu_list];
#Calculate width and height of the menu widget:
height = len(menu_list);
width = 0;
for entry in menu_list:
if len(entry) > width:
width = len(entry);
#Create the ListBox widget and put it on top of body:
self._listbox = urwid.AttrWrap(urwid.ListBox(content), attr[0]);
overlay = urwid.Overlay(self._listbox, body, ('fixed left', pos[0]),
width + 2, ('fixed top', pos[1]), height);
urwid.WidgetWrap.__init__(self, overlay);
def keypress(self, size, key):
"""
<RETURN> key selects an item, other keys will be passed to
the ListBox widget.
"""
if key == "enter":
(widget, foo) = self._listbox.get_focus();
(text, foo) = widget.get_text();
self.selected = text[1:]; #Get rid of the leading space...
else:
return self._listbox.keypress(size, key);
######################################################################
def menubar():
"""
Menu bar at the top of the screen
"""
menu_text = [('menuh', " P"), ('menu', "rogram "),
('menuh', "F"), ('menu', "oo "),
('menuh', "B"), ('menu', "ar ")]
return urwid.AttrWrap(urwid.Text(menu_text), 'menu');
######################################################################
def statusbar():
"""
Status bar at the bottom of the screen.
"""
status_text = "Statusbar -- Press Alt + <key> for menu entries";
return urwid.AttrWrap(urwid.Text(status_text), 'menu');
######################################################################
def body():
"""
Body (main part) of the screen
"""
main_text = " Hello world! \n\n I'm the main view."
return urwid.AttrWrap(urwid.Filler(urwid.Text(main_text)), 'bg');
######################################################################
class Dialog(urwid.WidgetWrap):
"""
Creates a BoxWidget that displays a message
Attributes:
b_pressed -- Contains the label of the last button pressed or None if no
button has been pressed.
edit_text -- After a button is pressed, this contains the text the user
has entered in the edit field
"""
b_pressed = None;
edit_text = None;
_blank = urwid.Text("");
_edit_widget = None;
_mode = None;
def __init__(self, msg, buttons, attr, width, height, body, ):
"""
msg -- content of the message widget, one of:
plain string -- string is displayed
(attr, markup2) -- markup2 is given attribute attr
[markupA, markupB, ... ] -- list items joined together
buttons -- a list of strings with the button labels
attr -- a tuple (background, button, active_button) of attributes
width -- width of the message widget
height -- height of the message widget
body -- widget displayed beneath the message widget
"""
#Text widget containing the message:
msg_widget = urwid.Padding(urwid.Text(msg), 'center', width - 4);
#GridFlow widget containing all the buttons:
button_widgets = [];
for button in buttons:
button_widgets.append(urwid.AttrWrap(
urwid.Button(button, self._action), attr[1], attr[2]));
button_grid = urwid.GridFlow(button_widgets, 12, 2, 1, 'center');
#Combine message widget and button widget:
widget_list = [msg_widget, self._blank, button_grid];
self._combined = urwid.AttrWrap(urwid.Filler(
urwid.Pile(widget_list, 2)), attr[0]);
#Place the dialog widget on top of body:
overlay = urwid.Overlay(self._combined, body, 'center', width,
'middle', height);
urwid.WidgetWrap.__init__(self, overlay);
def _action(self, button):
"""
Function called when a button is pressed.
Should not be called manually.
"""
self.b_pressed = button.get_label();
if self._edit_widget:
self.edit_text = self._edit_widget.get_edit_text();
######################################################################
def confirm_quit(ui, dim, display):
"""
\"Really quit?\"-dialog.
Return values:
False: Don't quit
True: Quit
"""
confirm = Dialog("Really quit?", ["Yes", "No"],
('menu', 'bg', 'bgf'), 30, 5, display);
keys = True;
#Event loop:
while True:
if keys:
ui.draw_screen(dim, confirm.render(dim, True));
keys = ui.get_input();
if "window resize" in keys:
dim = ui.get_cols_rows();
if "esc" in keys:
return False;
for k in keys:
confirm.keypress(dim, k);
if confirm.b_pressed == "Yes":
return True;
if confirm.b_pressed == "No":
return False;
######################################################################
def program_menu(ui, dim, display):
"""
Program menu
"""
program_menu = Menu(["Foo", "Bar", "Quit"],
('menu', 'menuf'), (0, 1), display);
keys = True;
#Event loop:
while True:
if keys:
ui.draw_screen(dim, program_menu.render(dim, True));
keys = ui.get_input();
if "window resize" in keys:
dim = ui.get_cols_rows();
if "esc" in keys:
return;
for k in keys:
#Send key to underlying widget:
program_menu.keypress(dim, k);
if program_menu.selected == "Quit":
if confirm_quit(ui, dim, display):
sys.exit(0)
else:
return
if program_menu.selected == "Foo":
#Do something
return
if program_menu.selected == "Bar":
#Do something
return
######################################################################
def foo_menu(ui, dim, display):
"""
Program menu
"""
foo_menu = Menu(["Blah", "Foo", "Stuff"],
('menu', 'menuf'), (10, 1), display);
keys = True;
#Event loop:
while True:
if keys:
ui.draw_screen(dim, foo_menu.render(dim, True));
keys = ui.get_input();
if "window resize" in keys:
dim = ui.get_cols_rows();
if "esc" in keys:
return;
for k in keys:
#Send key to underlying widget:
foo_menu.keypress(dim, k);
if foo_menu.selected == "Blah":
#Do something
return
if foo_menu.selected == "Foo":
#Do something
return
if foo_menu.selected == "Stuff":
#Do something
return
######################################################################
def bar_menu(ui, dim, display):
"""
Program menu
"""
bar_menu = Menu(["Blah", "Foo", "Stuff"],
('menu', 'menuf'), (16, 1), display);
keys = True;
#Event loop:
while True:
if keys:
ui.draw_screen(dim, bar_menu.render(dim, True));
keys = ui.get_input();
if "window resize" in keys:
dim = ui.get_cols_rows();
if "esc" in keys:
return;
for k in keys:
#Send key to underlying widget:
bar_menu.keypress(dim, k);
if bar_menu.selected == "Blah":
#Do something
return
if bar_menu.selected == "Foo":
#Do something
return
if bar_menu.selected == "Stuff":
#Do something
return
######################################################################
def run():
"""
Main part.
"""
#Set up displayed stuff:
dim = ui.get_cols_rows();
main_view = body();
display = urwid.Frame(main_view, menubar(), statusbar());
keys = True;
#Main event loop:
while True:
if keys:
#Redraw screen after user input:
display = urwid.Frame(main_view, menubar(), statusbar());
ui.draw_screen(dim, display.render(dim, True));
keys = ui.get_input();
if "window resize" in keys:
dim = ui.get_cols_rows();
if "meta P" in keys or "meta p" in keys:
#Show program menu:
program_menu(ui, dim, display)
if "meta F" in keys or "meta f" in keys:
#Show foo menu:
foo_menu(ui, dim, display)
if "meta B" in keys or "meta b" in keys:
#Show bar menu:
bar_menu(ui, dim, display)
######################################################################
#Entry point. Perform some initialisation: #
######################################################################
#init screen:
ui = urwid.curses_display.Screen();
ui.register_palette(
[('menu', 'black', 'dark cyan', 'standout'),
('menuh', 'yellow', 'dark cyan', ('standout', 'bold')),
('menuf', 'black', 'light gray'),
('bg', 'light gray', 'dark blue'),
('bgf', 'black', 'light gray', 'standout'),
('alert', 'light gray', 'dark red', ('standout', 'bold'))]);
#start main part:
ui.run_wrapper(run);
More information about the Urwid
mailing list