我是Python的urwid控制台小部件的新手,并试图学习它。为了进行实验,我试图制作一个屏幕,其中标题“Foobar”位于顶部,而在底部我将在左列中有2个图形(我相信这将被称为正文)。
到目前为止,我试过这个:
class SwitchingPadding(urwid.Padding):
def padding_values(self, size, focus):
maxcol = size[0]
width, ignore = self.original_widget.pack(size, focus=focus)
if maxcol > width:
self.align = "left"
else:
self.align = "right"
return urwid.Padding.padding_values(self, size, focus)
class Graphics():
palette = [
('body', 'black', 'light gray', 'standout'),
('header', 'white', 'dark red', 'bold'),
('button normal','light gray', 'dark blue', 'standout'),
('button select','white', 'dark green'),
('button disabled','dark gray','dark blue'),
('edit', 'light gray', 'dark blue'),
('title', 'white', 'black'),
('chars', 'light gray', 'black'),
('exit', 'white', 'dark cyan'),
('bg background','light gray', 'black'),
('bg 1', 'black', 'dark blue', 'standout'),
('bg 1 smooth', 'dark blue', 'black'),
('bg 2', 'black', 'dark cyan', 'standout'),
('bg 2 smooth', 'dark cyan', 'black'),
]
graph_num_bars = 2
graph_samples_per_bar = 10
def update_graph(self, force_update=False):
o = self.get_offset_now()
if o == self.last_offset and not force_update:
return False
self.last_offset = o
gspb = self.graph_samples_per_bar
r = gspb * self.graph_num_bars
d, max_value, repeat = self.controller.get_data( o, r )
l = []
for n in range(self.graph_num_bars):
value = sum(d[n*gspb:(n+1)*gspb])/gspb
# toggle between two bar types
if n & 1:
l.append([0,value])
else:
l.append([value,0])
self.graph.set_data(l,max_value)
def setup(self):
#Create Title for Frame widget
self.title = urwid.BigText("Foobar", "Thin6x6Font")
bt = SwitchingPadding(self.title, 'left', None)
bt = urwid.AttrWrap(bt, 'title')
bt = urwid.Filler(bt, 'bottom', None, 7)
bt = urwid.BoxAdapter(bt, 7)
def bar_graph(self):
satt = None
w = urwid.BarGraph(['bg background','bg 1','bg 2'], satt=satt)
return w
def main_window(self):
self.graph = self.bar_graph()
self.graph_wrap = urwid.WidgetWrap( self.graph )
vline = urwid.AttrWrap( urwid.SolidFill(u'\u2502'), 'line')
c = self.graph_controls()
w = urwid.Columns([('weight',2,self.graph_wrap),
('fixed',1,vline), c],
dividechars=1, focus_column=2)
w = urwid.Padding(w,('fixed left',1),('fixed right',0))
w = urwid.AttrWrap(w,'body')
w = urwid.LineBox(w)
w = urwid.AttrWrap(w,'line')
w = self.main_shadow(w)
return w
def main(self):
self.view = self.setup()
self.loop = urwid.MainLoop(self.view, self.palette)
self.loop.run()
def main():
Graphics().main()
if '__main__'==__name__:
main()
但我陷入了困境:
one@development ~/try $ python foo.py
Traceback (most recent call last):
File "foo.py", line 92, in <module>
main()
File "foo.py", line 89, in main
Graphics().main()
File "foo.py", line 85, in main
self.loop.run()
File "/usr/lib64/python2.7/site-packages/urwid/main_loop.py", line 272, in run
self.screen.run_wrapper(self._run)
File "/usr/lib64/python2.7/site-packages/urwid/raw_display.py", line 242, in run_wrapper
return fn()
File "/usr/lib64/python2.7/site-packages/urwid/main_loop.py", line 312, in _run
self.draw_screen()
File "/usr/lib64/python2.7/site-packages/urwid/main_loop.py", line 563, in draw_screen
canvas = self._topmost_widget.render(self.screen_size, focus=True)
AttributeError: 'NoneType' object has no attribute 'render'
one@development ~/try $
任何人都知道为什么?
答案 0 :(得分:1)
self._topmost_widget为None。检查它的创建或更新位置。