def main():
palette = [
('body','black','dark cyan', 'standout'),
('foot','light gray', 'black'),
('key','light cyan', 'black', 'underline'),
('title', 'white', 'black',),
]
footer_text = [
('title', "Fibonacci Set Viewer"), " ",
('key', "UP"), ", ", ('key', "DOWN"), ", ",
('key', "PAGE UP"), " and ", ('key', "PAGE DOWN"),
" move view ",
('key', "Q"), " exits",
]
def exit_on_q(input):
if input in ('q', 'Q'):
raise urwid.ExitMainLoop()
listbox = urwid.ListBox(FibonacciWalker())
footer = urwid.AttrMap(urwid.Text(footer_text), 'foot')
view = urwid.Frame(urwid.AttrWrap(listbox, 'body'), footer=footer)
loop = urwid.MainLoop(view, palette, unhandled_input=exit_on_q)
loop.run()
python类Frame()的实例源码
def __init__(self, client):
self.client = client
self.screen = urwid.raw_display.Screen()
# self.screen = self.DummyScreen()
self.frame = urwid.Frame(
client.default_view,
footer=urwid.Text("", align='center'),
)
self.client.frame = self.frame
self.urwid_loop = urwid.MainLoop(
self.frame,
screen=self.screen,
palette=palette,
event_loop=self.FixedAsyncLoop(loop=client.loop),
unhandled_input=client.handle_keypresses,
pop_ups=True
)
def switch_states(self, state):
# this method is run to switch states, it reassigns what content is in the Frame
if state == 'editor':
self.top.contents['header'] = (self.status, None)
self.top.contents['body'] = (self.body_col, None)
self.top.contents['footer'] = (self.foot_col, None)
if self.layout:
self.top.contents['footer'] = (self.status, None)
self.top.contents['header'] = (self.foot_col, None)
elif state == 'openfile':
path = strip_path(self.listbox.fname)
self.browser = urwid.TreeListBox(urwid.TreeWalker(DirectoryNode(path, self)))
self.top.contents['header'] = (self.oftbar, None)
self.top.contents['body'] = (self.browser, None)
self.top.contents['footer'] = (self.ofbbar, None)
self.ofbbar.set_text('')
self.state = state
def __init__(self, title, command_caption='Command: (Tab to switch focus to upper frame, where you can scroll text)', cmd_cb=None, max_size=1000):
self.header=urwid.Text(title)
self.model=urwid.SimpleListWalker([])
self.body=ListView(self.model, lambda: self._update_focus(False), max_size=max_size )
self.input=Input(lambda: self._update_focus(True))
foot=urwid.Pile([urwid.AttrMap(urwid.Text(command_caption), 'reversed'),
urwid.AttrMap(self.input,'normal')])
urwid.Frame.__init__(self,
urwid.AttrWrap(self.body, 'normal'),
urwid.AttrWrap(self.header, 'reversed'),
foot)
self.set_focus_path(['footer',1])
self._focus=True
urwid.connect_signal(self.input,'line_entered',self.on_line_entered)
self._cmd=cmd_cb
self._output_styles=[s[0] for s in self.PALLETE]
self.eloop=None
def __init__(self, title, command_caption='Command: (Tab to switch focus to upper frame, where you can scroll text)', cmd_cb=None, max_size=1000):
self.header=urwid.Text(title)
self.model=urwid.SimpleListWalker([])
self.body=ListView(self.model, lambda: self._update_focus(False), max_size=max_size )
self.input=Input(lambda: self._update_focus(True))
foot=urwid.Pile([urwid.AttrMap(urwid.Text(command_caption), 'reversed'),
urwid.AttrMap(self.input,'normal')])
urwid.Frame.__init__(self,
urwid.AttrWrap(self.body, 'normal'),
urwid.AttrWrap(self.header, 'reversed'),
foot)
self.set_focus_path(['footer',1])
self._focus=True
urwid.connect_signal(self.input,'line_entered',self.on_line_entered)
self._cmd=cmd_cb
self._output_styles=[s[0] for s in self.PALLETE]
self.eloop=None
def __init__(self):
self.prefs = bbjrc("load")
self.mode = None
self.thread = None
self.usermap = {}
self.window_split = False
self.last_pos = None
# these can be changed and manipulated by other methods
self.walker = urwid.SimpleFocusListWalker([])
self.box = ActionBox(self.walker)
self.body = urwid.AttrMap(
urwid.LineBox(
self.box,
title=self.prefs["frame_title"],
**frame_theme()),
"default"
)
self.loop = urwid.MainLoop(
urwid.Frame(self.body),
palette=colormap,
handle_mouse=self.prefs["mouse_integration"])
def __init__(self, title,
command_caption='Command: (Tab to switch focus to upper frame, where you can scroll text)',
cmd_cb=None, max_size=1000):
self.header = urwid.Text(title)
self.model = urwid.SimpleListWalker([])
self.body = ListView(self.model, lambda: self._update_focus(False), max_size=max_size)
self.input = Input(lambda: self._update_focus(True))
foot = urwid.Pile([urwid.AttrMap(urwid.Text(command_caption), 'reversed'),
urwid.AttrMap(self.input, 'normal')])
urwid.Frame.__init__(self,
urwid.AttrWrap(self.body, 'normal'),
urwid.AttrWrap(self.header, 'reversed'),
foot)
self.set_focus_path(['footer', 1])
self._focus = True
urwid.connect_signal(self.input, 'line_entered', self.on_line_entered)
self._cmd = cmd_cb
self._output_styles = [s[0] for s in self.PALLETE]
self.eloop = None
def ftbtest(self, desc, focus_part, header_rows, footer_rows, size,
focus, top, bottom):
class FakeWidget:
def __init__(self, rows, want_focus):
self.ret_rows = rows
self.want_focus = want_focus
def rows(self, size, focus=False):
assert self.want_focus == focus
return self.ret_rows
header = footer = None
if header_rows:
header = FakeWidget(header_rows,
focus and focus_part == 'header')
if footer_rows:
footer = FakeWidget(footer_rows,
focus and focus_part == 'footer')
f = urwid.Frame(None, header, footer, focus_part)
rval = f.frame_top_bottom(size, focus)
exp = (top, bottom), (header_rows, footer_rows)
assert exp == rval, "%s expected %r but got %r"%(
desc,exp,rval)
def test_focus_path(self):
# big tree of containers
t = urwid.Text(u'x')
e = urwid.Edit(u'?')
c = urwid.Columns([t, e, t, t])
p = urwid.Pile([t, t, c, t])
a = urwid.AttrMap(p, 'gets ignored')
s = urwid.SolidFill(u'/')
o = urwid.Overlay(e, s, 'center', 'pack', 'middle', 'pack')
lb = urwid.ListBox(urwid.SimpleFocusListWalker([t, a, o, t]))
lb.focus_position = 1
g = urwid.GridFlow([t, t, t, t, e, t], 10, 0, 0, 'left')
g.focus_position = 4
f = urwid.Frame(lb, header=t, footer=g)
self.assertEqual(f.get_focus_path(), ['body', 1, 2, 1])
f.set_focus_path(['footer']) # same as f.focus_position = 'footer'
self.assertEqual(f.get_focus_path(), ['footer', 4])
f.set_focus_path(['body', 1, 2, 2])
self.assertEqual(f.get_focus_path(), ['body', 1, 2, 2])
self.assertRaises(IndexError, lambda: f.set_focus_path([0, 1, 2]))
self.assertRaises(IndexError, lambda: f.set_focus_path(['body', 2, 2]))
f.set_focus_path(['body', 2]) # focus the overlay
self.assertEqual(f.get_focus_path(), ['body', 2, 1])
def __init__(self, data, header):
title = [
(4, urwid.AttrWrap(urwid.Text('#'), 'body', 'focus')),
(2, urwid.AttrWrap(urwid.Text(''), 'body', 'focus')),
(10, urwid.AttrWrap(urwid.Text('Tag'), 'body', 'focus')),
urwid.AttrWrap(urwid.Text('Title'), 'body', 'focus'),
(15, urwid.AttrWrap(urwid.Text('Acceptance'), 'body', 'focus')),
(15, urwid.AttrWrap(urwid.Text('Difficulty'), 'body', 'focus')),
]
title_column = urwid.Columns(title)
self.marks = load_marks()
items = make_itemwidgets(data, self.marks)
self.listbox = urwid.ListBox(urwid.SimpleListWalker(items))
header_pile = urwid.Pile([header, title_column])
urwid.Frame.__init__(self, urwid.AttrWrap(self.listbox, 'body'), header=header_pile)
self.last_sort = {'attr': 'id', 'reverse': True}
self.last_search_text = None
def keypress(self, size, key):
key = vim_key_map(key)
ignore_key = ('h', 'left')
if key in ignore_key:
pass
elif key is '1':
self.sort_list('id')
elif key is '2':
self.sort_list('title')
elif key is '3':
self.sort_list('acceptance')
elif key is '4':
self.sort_list('difficulty', cmp=self.difficulty_cmp)
elif key is 'home':
self.listbox.focus_position = 0
elif key is 'end':
self.listbox.focus_position = len(self.listbox.body) - 1
elif key is 'n':
self.handle_search(self.last_search_text, True)
else:
return urwid.Frame.keypress(self, size, key)
def keypress(self, size, key):
key = vim_key_map(key)
ignore_key = ('l', 'right', 'enter')
if key in ignore_key:
pass
# edit sample code
if key is 'e':
self.edit_code()
# edit new sample code
elif key is 'n':
self.edit_code(True)
# open discussion page from default browser
elif key is 'd':
url = self.get_discussion_url()
webbrowser.open(url)
# open solutions page from default browser
elif key is 'S':
url = self.get_solutions_url()
webbrowser.open(url)
else:
return urwid.Frame.keypress(self, size, key)
def __init__(
self, title, login,
command_caption='Command: (Tab to switch focus to upper '
'frame, where you can scroll text)\nType exit or quit '
'to close', max_size=1000):
self.header = urwid.Text(title)
self.model = urwid.SimpleListWalker([])
self.body = ListView(
self.model, lambda: self._update_focus(False), max_size=max_size)
self.input = Input(lambda: self._update_focus(True))
foot = urwid.Pile([
urwid.AttrMap(
urwid.Text(command_caption),
'reversed'),
urwid.AttrMap(self.input, 'normal')])
urwid.Frame.__init__(self,
urwid.AttrWrap(self.body, 'normal'),
urwid.AttrWrap(self.header, 'reversed'),
foot)
self.set_focus_path(['footer', 1])
self._focus = True
urwid.connect_signal(self.input,
'line_entered',
self.on_line_entered)
self._output_styles = [s[0] for s in self.PALLETE]
self.eloop = None
self.login = login
def keypress(self, size, key):
if key == 'tab':
self.switch_focus()
return urwid.Frame.keypress(self, size, key)
def Widget(self, widget):
"""Setter for topmost widget, used to switch view modes.
@widget - widget instance, most probably ur.Frame
Assigns a new topmost widget to be displayed, essentially
allowing us to switch between modes, like board view,
main menu, etc.
"""
self._widget_stack.append(widget)
self.widget = widget
def frameBody(self):
"""Returns body (a list of widgets in the form of
Simple[Focus]ListWalker) of top-level Frame widget to manipulate."""
return self.widget.original_widget.contents["body"][0]. \
original_widget.body
def run(self):
"""This method needs to be called to actually start the display.
To switch to another view (another Frame widget), use the
`@widget.setter` property of Loop. To return to earlier view
(or close a pop-up), use `@widget.deleter`. To interact with the
body of current Frame, use `@frameBody` property.
"""
frame = self.MOTD_screen()
# Top-level widget finished initializing, so let's assign it.
self.loop.Widget = ur.AttrMap(frame, "bg", None)
self.loop.run()
def MOTD_screen(self):
"""MOTD display method - first screen shown."""
self.motd_flag = True
self.header = self.make_header()
mid = ur.Padding(ur.ListBox(
ur.SimpleFocusListWalker([
self.div, ur.Text([("red", "Welcome to "),
("yellow", "sshchan!\n==========="),
("red", "========\n"),
("green", "SERVER: "),
self.config.server_name,
("green", "\nMOTD:\n")], "center"),
self.div])), "center", ("relative", 60), self.width,
self.margin, self.margin)
# TODO: add currently online users to the footer.
self.footer = ur.AttrMap(ur.Text(
" " + self.config.server_name + " " + self.config.version +
" | Press H for help", align="center"), "reverse", None)
try:
with open(self.config.motd, 'r') as m:
buf = m.read()
except FileNotFoundError:
buf = "---sshchan! woo!---"
motd = ur.Text(buf, "center")
mid.original_widget.body.append(motd)
mid.original_widget.body.append(self.div)
return ur.Frame(mid, self.header, self.footer, focus_part="body")
def show_help(self):
"""Create and return Frame object containing help docs."""
# Flags are gr8 against bugs.
self.help_flag = True
help_header = ur.Text(("green", "SSHCHAN HELP"), "center")
pg1 = ur.Text(
[("bold", "sshchan "), "is a textboard environment designed \
to run on remote SSH servers with multiple anonymous users simultaneously \
browsing and posting."], "center")
pg2 = ur.Text(("bold", "Keybindings:"))
pg3 = ur.Text([("green", "TAB"),
(
None,
" - switch focus between main body and top bar")])
pg4 = ur.Text(
[("green", "H h"), (None, " - display this help dialog")])
pg5 = ur.Text(
[("green", "B b"), (None, " - view available boards")])
pg6 = ur.Text(
[("green", "ESC"),
(
None,
" - go back one screen (exits on MOTD screen)")])
back_btn = ur.AttrMap(
ur.Button("Back", self.button_press, "back"), "red", "reverse")
help_body = ur.Padding(ur.ListBox(ur.SimpleListWalker([
self.div, help_header, self.div, pg1, self.div, pg2,
pg3, pg4, pg5, pg6, self.div, back_btn])),
"center", self.width, 0, self.margin, self.margin)
return ur.AttrMap(ur.Frame(help_body, self.header, self.footer,
"body"), "bg")
def print_thread(self, button, thread):
thr_no = self.board.thread_exists(int(thread))
thr_body = self.board.get_index()[thr_no]
replies = ur.SimpleFocusListWalker([])
subject = ("reverse_red", thr_body[1])
if subject[1] == "":
subject = (None, "")
op = self.parse_post(thr_body[2])
op_info = ur.Text([("reverse_green", op["name"]),
" " + op["stamp"] + " ", subject])
op_btn = CleanButton(
"No. " + op["id"], self.reply_box, op["id"])
op_widget = ur.AttrMap(ur.Columns(
[("pack", op_info), ("pack", op_btn)], 1), "reverse")
replies.extend([op_widget, op["text"], self.parent.div])
if len(thr_body) > 3:
for postno in range(3, len(thr_body)):
reply = self.parse_post(thr_body[postno])
reply_info = ur.Text(
[("green", reply["name"]), " " + reply["stamp"]])
reply_btn = CleanButton(
"No. " + reply["id"], self.reply_box, reply["id"])
reply_widget = ur.Columns(
[("pack", reply_info), ("pack", reply_btn)],
1)
replies.extend([reply_widget, reply["text"], self.parent.div])
contents = ur.ListBox(replies)
contents.set_focus(0)
self.loop.Widget = ur.Frame(
contents, self.parent.header, self.parent.footer, "body")
def __init__(self, pubpen):
self.pubpen = pubpen
#
# Always displayed widgets
#
self.menu_bar_window = MenuBarWindow(self.pubpen)
self.info_window = InfoWindow(self.pubpen)
self.main_window = MainWindow(self.pubpen)
self.msg_window = MessageWindow(self.pubpen)
pile = urwid.Pile((self.main_window,
(self.msg_window.height, self.msg_window),
))
cols = urwid.Columns((pile, (15, self.info_window)))
layout = urwid.Pile((
('pack', self.menu_bar_window),
('weight', 1, cols),
))
self.top = urwid.Frame(layout)
super().__init__(self.top)
tline = self.tline_widget[0]
self.status_bar = StatusBar(self.pubpen, spacer=tline.div_char)
self.tline_widget.contents.clear()
self.tline_widget.contents.extend((
(tline, self.tline_widget.options('given', 1, False)),
(self.status_bar, self.tline_widget.options('weight', 1, False)),
(tline, self.tline_widget.options('given', 1, False)),
))
def __init__(self, pubpen, cli_args):
super().__init__(pubpen, cli_args)
# Note: We don't have any extra command line args
# Windows
self.title_card = TitleScreen(pubpen)
self.login_screen = LoginScreen(pubpen)
self.main_window = MainScreen(pubpen)
self.root_win = urwid.Frame(urwid.SolidFill(' '))
# Arrange the widgets
self.show_title_card()
# Connect to UI events
urwid.connect_signal(self.title_card, 'close_title_card', self.show_login_screen)
urwid.connect_signal(self.login_screen, 'logged_in', self.show_main_window)
# Setup the main loop
self.urwid_loop = urwid.MainLoop(self.root_win,
event_loop=urwid.AsyncioEventLoop(loop=self.pubpen.loop),
palette=(('reversed', 'standout', ''),),)
def makeFrame(self, data):
"""
Returns a new frame that is formatted correctly with respect to the window's dimensions.
:param data: tuple of (answers, question_title, question_desc, question_stats, question_url)
:return: a new urwid.Frame object
"""
answers, question_title, question_desc, question_stats, question_url = data
self.data = data
self.question_desc = question_desc
self.url = question_url
self.answer_text = AnswerText(answers)
self.screenHeight, screenWidth = subprocess.check_output(['stty', 'size']).split()
self.question_text = urwid.BoxAdapter(QuestionDescription(question_desc), int(max(1, (int(self.screenHeight) - 9) / 2)))
answer_frame = urwid.Frame(
header= urwid.Pile( [
header_for_display,
QuestionTitle(question_title),
self.question_text,
QuestionStats(question_stats),
urwid.Divider('-')
]),
body=self.answer_text,
footer= urwid.Pile([
QuestionURL(question_url),
UnicodeText(u'\u2191: previous answer, \u2193: next answer, o: open in browser, \u2190: back')
])
)
return answer_frame
def __init__(self, main_widget):
self.main_widget = main_widget
self.pop_up = urwid.Frame(urwid.WidgetPlaceholder(None))
self.w_placeholder = urwid.WidgetPlaceholder(self.main_widget)
self.pop_up_overlay = urwid.Overlay(urwid.LineBox(self.pop_up),
self.main_widget,
'center',
('relative', 60),
'middle',
('relative', 60))
def getFrame(self):
urwid.AttrMap(self.getEdit(), 'input')
frame_widget = urwid.Frame(
header=self.getHeader(),
body=self.getConsole(),
footer=urwid.AttrMap(self.getEdit(), 'input'),
focus_part='footer')
return frame_widget
def __init__(self, movies):
footer=urwid.AttrWrap(urwid.Text('Press q to exit, use up and down arrow to navigate, press Enter to select'), 'footer')
items = self.make_items(movies)
self.listbox = urwid.ListBox(urwid.SimpleListWalker(items))
top = urwid.Overlay(self.listbox, urwid.SolidFill(' '),
align='center', width=('relative', 60),
valign='middle', height=('relative', 60),
min_width=20, min_height=9)
urwid.Frame.__init__(self, urwid.AttrWrap(top, 'body'), footer=footer)
def keypress(self, size, key):
global loop
if key is 'enter':
loop.data = self.listbox.get_focus()[0].data
raise urwid.ExitMainLoop()
return urwid.Frame.keypress(self, size, key)
def keypress(self, size, key):
if key=='tab':
self.switch_focus()
return urwid.Frame.keypress(self, size, key)
def keypress(self, size, key):
if key=='tab':
self.switch_focus()
return urwid.Frame.keypress(self, size, key)
def __init__(self, db=None, cmd=None):
self.db = papis.database.Database()
self.header_string = "Papis"
self.status_string = "q: quit buffer, Q: quit Papis, ?: help"
self.view = urwid.Frame(urwid.SolidFill())
self.set_header()
self.set_status()
if not cmd:
cmd = ['search', '']
if cmd[0] == 'search':
query = ' '.join(cmd[1:])
self.buffer = Search(self, query)
elif cmd[0] == 'bibview':
query = ' '.join(cmd[1:])
self.buffer = Bibview(self, query)
elif cmd[0] == 'help':
target = None
if len(cmd) > 1:
target = cmd[1]
if isinstance(target, str):
target = None
self.buffer = Help(self, target)
else:
self.buffer = Help(self)
self.set_status("Unknown command '%s'." % (cmd[0]))
self.merge_palette(self.buffer)
self.view.body = urwid.AttrMap(self.buffer, 'body')
self.mainloop = urwid.MainLoop(
self.view,
self.palette,
unhandled_input=self.keypress,
handle_mouse=False,
)