我正在尝试编写一个具有不同视图的程序。
我尝试创建一个使用 urwid 处理不同视图的类,并将视图代码与其他代码分开。但是经过很多不同的尝试,我不知道从哪里开始了。
我需要哪些 urwid 对象来彻底擦除和重绘屏幕?以及如何封装它们以便我可以在用户输入后切换视图?
我正在尝试编写一个具有不同视图的程序。
我尝试创建一个使用 urwid 处理不同视图的类,并将视图代码与其他代码分开。但是经过很多不同的尝试,我不知道从哪里开始了。
我需要哪些 urwid 对象来彻底擦除和重绘屏幕?以及如何封装它们以便我可以在用户输入后切换视图?
来自Urwid 文档:
MainLoop 显示的最顶层小部件必须作为第一个参数传递给构造函数。 如果要在运行时更改最顶层的小部件,可以将新的小部件分配给 MainLoop 对象的 MainLoop.widget 属性。这对于具有多种不同模式或视图的应用程序很有用。
现在看一些代码:
import urwid
# This function handles input not handled by widgets.
# It's passed into the MainLoop constructor at the bottom.
def unhandled_input(key):
if key in ('q','Q'):
raise urwid.ExitMainLoop()
if key == 'enter':
try:
## This is the part you're probably asking about
loop.widget = next(views).build()
except StopIteration:
raise urwid.ExitMainLoop()
# A class that is used to create new views, which are
# two text widgets, piled, and made into a box widget with
# urwid filler
class MainView(object):
def __init__(self,title_text,body_text):
self.title_text = title_text
self.body_text = body_text
def build(self):
title = urwid.Text(self.title_text)
body = urwid.Text(self.body_text)
body = urwid.Pile([title,body])
fill = urwid.Filler(body)
return fill
# An iterator consisting of 3 instantiated MainView objects.
# When a user presses Enter, since that particular key sequence
# isn't handled by a widget, it gets passed into unhandled_input.
views = iter([ MainView(title_text='Page One',body_text='Lorem ipsum dolor sit amet...'),
MainView(title_text='Page Two',body_text='consectetur adipiscing elit.'),
MainView(title_text='Page Three',body_text='Etiam id hendrerit neque.')
])
initial_view = next(views).build()
loop = urwid.MainLoop(initial_view,unhandled_input=unhandled_input)
loop.run()
简而言之,我使用了一个全局键处理函数来监听用户按下的某个序列,并在接收到该序列时,我的键处理函数使用 MainView 类构建一个新的视图对象并替换loop.widget
为该对象。当然,在实际应用程序中,您将希望在视图类中的特定小部件上创建信号处理程序,而不是对所有用户输入使用全局 unhandled_input 函数。您可以在此处阅读有关 connect_signal 函数的信息。
请注意 Signal Functions 文档中有关垃圾收集的部分:如果您打算编写具有许多视图的内容,即使您替换了它们,它们也会保留在内存中,因为 signal_handler 是一个闭包,它保留了一个引用隐式地传递给该小部件,因此您需要将weak_args
命名参数传递给urwid.connect_signal
函数,以告诉 Urwid 在事件循环中未主动使用它时让它离开。