现在,我们研究 main() 函数,看看 curses_txt2html 做些什么: 字串8
curses_txt2html.py main() 函数和事件循环 字串9 def
main
(stdscr):
# Frame the interface area at fixed VT100 size
global
screen
screen = stdscr.subwin(23, 79, 0, 0)
screen.box()
screen.hline(2, 1, curses.ACS_HLINE, 77)
screen.refresh()
# Define the topbar menus
file_menu = (
"File",
"file_func()")
proxy_menu = (
"Proxy Mode",
"proxy_func()")
doit_menu = (
"Do It!",
"doit_func()")
help_menu = (
"Help",
"help_func()")
exit_menu = (
"Exit",
"EXIT")
# Add the topbar menus to screen object
topbar_menu((file_menu, proxy_menu, doit_menu,
help_menu, exit_menu))
# Enter the topbar menu loop
while
topbar_key_handler():
draw_dict()
字串9
根据由空行隔开的三部分,很容易理解 main() 函数。
第一部分执行应用程序外观的常规设置。为了建立应用程序元素之间的可预期间隔,交互式区域限制在 80 x 25 VT100/PC 屏幕大小(即使实际的终端窗口更大)。程序围绕这个子窗口绘制一个框,并使用水平线画出顶栏菜单的视觉偏移量。
字串2
第二部分建立应用程序所使用的菜单。函数 topbar_menu() 使用一些技巧将热键绑定到应用程序操作并用期望的视觉属性来显示菜单。请获取源码档案(请参阅 参考资料 )以查看所有代码。 topbar_menu() 应该是非常普通的。(欢迎将它合并到您自己的应用程序中。)非常重要的是一旦绑定了热键,它们就 eval() 与菜单相关的字节组第二个元素中包含的字符串。例如,激活以上设置中的 "File" 菜单将调用 "eval("file_func()")"。所以就要求应用程序定义叫做 file_func() 的函数,要求它返回一个布尔 (Boolean) 值以表示是否达到应用程序终止状态。 字串9
第三部分只有两行,但这正是整个应用程序实际运行的部分。函数 topbar_key_handler() 就像它的名称所暗示的:它等待击键,然后处理它们。击键处理程序可以会返回 Boolean false 值。(如果是这样,则应用程序终止。)该应用程序中,键处理程序主要是检查第二段中绑定的键。但即使您的 curses 应用程序绑定键的方式与该应用程序不同,您仍要使用类似的事件循环。处理程序的关键部分很可能使用以下这行代码: 字串4
c = screen.getch()# read a keypress 对 draw_dict() 的调用只是事件循环中唯一的代码。此函数绘制了 screen 窗口中几处位置中的值。但在应用程序中,您可能想要将以下这行代码:
screen.refresh() # redraw the screen w/ any new output 字串8
加到绘制/刷新函数中(或只加到事件循环本身中)。 字串7
获取用户输入
字串4
curses 应用程序以击键事件的形式获取所有用户输入。我们已经看过了 .getch() 方法,现在让我们看一下将 .getch() 与其它输入方法组合在一起的例子 .getstr() 。以下就是我们以前提到的 file_func() 函数的缩写版本(它由 "File" 菜单激活)。
字串1
curses_txt2html.py file_func() 函数 字串9 def 字串2
file_func
():
s = curses.newwin(5,10,2,1)
s.box()
s.addstr(1,2,
"I", hotkey_attr)
s.addstr(1,3,
"nput", menu_attr)
s.addstr(2,2,
"O", hotkey_attr)
s.addstr(2,3,
"utput", menu_attr)
s.addstr(3,2,
"T", hotkey_attr)
s.addstr(3,3,
"ype", menu_attr)
s.addstr(1,2,
"", hotkey_attr)
s.refresh()
c = s.getch()
if
c
in
(ord(
'I'), ord(
'i'), curses.KEY_ENTER, 10):
curses.echo()
s.erase()
screen.addstr(5,33,
" "*43, curses.A_UNDERLINE)
cfg_dict[
'source'] = screen.getstr(5,33)
curses.noecho()
else
:
curses.beep()
s.erase()
return
CONTINUE
此函数组合了几个 curses 特性。它做的第一件事就是创建另一个窗口对象。由于这个新窗口对象是 "File" 选择项的实际下拉菜单,所以程序使用 .box() 方法围着它绘制了一个框架。在窗口 s 中,程序绘制了几个下拉菜单选项。使用了一种稍微费力的方法突出显示了每个选项的热键,这样就与选项描述的其余部分形成了对比。(请查看完整源码(请参阅 参考资料 )中的 topbar_menu() 以学习一种能稍微自动处理突出显示的方法。)最后的 .addstr() 调用将光标移到缺省菜单选项。如同主屏幕一样, s.refresh() 实际上显示了画到窗口对象上的元素。 字串8
绘制了下拉菜单后,程序使用简单的 s.getch() 调用来获取用户的选择项。在演示应用程序中,菜单只响应热键,但不响应箭头键或可移动突出显示栏。可以通过捕捉附加键操作并在下拉菜单中设置事件循环来构建这些更复杂的菜单功能。但这个例子已经足够说明这种概念了。 字串1
接着,程序将刚读取的击键与各种热键值做比较。在本例中,热键的大小写都可以激活下拉菜单选项,并且可以使用 ENTER 键激活缺省选项。(curses 特殊键常量看上去并不完全可靠,我发现必须添加实际的 ASCII 值 "10" 来捕捉 ENTER 键。)请注意,如果要执行字符值比较,那么要将字符串封装到 ord() 内置 Python 函数中。
![我要研发网[www.51dev.com]](/templets/images/toplogo.gif)
