pythoncursesaddstr错误 - 但仅在我的计算机上
我正在编写一个小程序,它获取一个列表并在curses中生成一个菜单(直接,标准库或其他什么,电池包括python的curses),当我注意到最奇怪的问题(如果你愿意,一个有大量评论的副本)整个程序如下)。简而言之,当接受 os.listdir 生成的列表的结果时,curses 会崩溃并出现 addstr
ERR,但是,如果我向它提供硬编码列表,它就可以正常工作。当然,这完全没有意义,对吧?列表就是列表就是列表,任何其他名称的列表仍然应该是列表,对吗?
为了让事情变得更复杂,我将代码发送给了我的一个主要在 python2.6 中工作的朋友(我的代码最初是在 python3.1 中工作的)。他取消了 broken_input()
调用的注释(该调用向程序提供 os.listdir
生成的信息),并表示这对他来说效果很好。我安装了 python 2.6 和 3.1,所以我更改了 shebang 以使程序在 2.6 中运行,并且(在 broken_input()
未注释的情况下)对我来说,它仍然抛出 addstr
ERR(但在硬编码输入下运行良好......当然,顺便说一句,除了概念证明之外,完全没用)。
因此,我的问题是:我的 python 安装中有什么问题(我正在运行 Ubuntu lucid,安装了 python2.6.5 和 3.1),如果是这样,我该如何修复它,以便我可以得到curses来执行这个正确编码。而且,如果这不是我的Python安装,我怎样才能从curses中获得相同的功能(即:从包含任意数量项目的列表中绘制菜单,对它们进行编号,以便用户可以根据项目编号进行选择)。
#!/usr/bin/env python3.1
"""curses_mp3eater.py: a curses-based implementation of my mp3eater program;
diplays the contents of cwd, allows user to make a selection. But I'm having
problems getting it to iterate over a list.
v0.1 03.14.11
by skookie sprite
[email protected]
"""
import curses, curses.wrapper, os, sys
def working_input():
"""the following is demo code to demonstrate my problem... main will accept the following,
but won't accept the product of a directorylist for reasons that I can't figure out."""
dircontents=['this','is','a','list','','and','it','will','iterate','fine','in','the','(main) function.']
return dircontents
def broken_input():
"""this is the code that I NEED to have work... but for reasons beyond me will not iterate in
the main function. It's a simple list of the contents of the CWD."""
cwd=os.getcwd()
dircontents=[]
for item in os.listdir(cwd):
dircontents += [item]
return dircontents
def main(stdscr):
"""This is the program. Designed to take a list of stuff and display it. If I can solve
that hurdle, I'll add selection mechanisms, and break it across screens - amongst other
things. But, currently, it can only accept the demo code. Uncomment one or the other to
see what I mean."""
#broken_input returns an addstr() ERR, but I don't see the difference between working_input
#and broken_input as they are both just lists.
#working_input() is demo code that illustrates my problem
stuffin=working_input()
#stuffin=broken_input()
#the rest of this stuff works. The problem is with the input. Why?
linenumber=int()
linenumber=6
itemnumber=int()
itemnumber=1
stdscr.clear()
stdscr.border(0)
for item in stuffin:
stdscr.addstr(linenumber, 10, '%s - %s' % (itemnumber, item), curses.A_NORMAL)
linenumber += 1
itemnumber += 1
curses.doupdate()
stdscr.getch()
if __name__ == '__main__':
curses.wrapper(main)
I was writing a little program that takes a list and generates a menu out of it in curses (straight up, standard library or whatever, batteries included python's curses) when I noticed the strangest problem (if you'd like, a heavily commented copy of the entire program is below). Simply put, when accepting the results of an os.listdir
generated list, curses crashes with an addstr
ERR, BUT, if I feed it a hardcoded list, it works fine. This, of course, makes absolutely no sense, right? A list is a list is a list and a list by any other name should still be a list, right?
To make things even more complicated, I sent the code to a friend of mine who works mainly in python2.6 (mine was originally written to work in python3.1). He uncommented the broken_input()
call (which feeds the program the os.listdir
generated information) and said that it worked fine for him. I have both python 2.6 and 3.1 installed, so I changed my shebang to make the program run in 2.6, and (with the broken_input()
uncommented) for me, it still throws the addstr
ERR (yet runs fine with the hardcoded input... which is, of course, btw, entirely useless apart from proof of concept).
Thus, my question is this: is there something broken in my python installation (I'm running Ubuntu lucid, with python2.6.5 and 3.1 installed), and, if so, how do I fix it so I can get curses to execute this code properly. And, if it's not my python installation, how can I get the same functionality out of curses (i.e.: paint a menu from a list containing an arbitrary number of items, numbering them so that the user can make a selection based on the item number).
#!/usr/bin/env python3.1
"""curses_mp3eater.py: a curses-based implementation of my mp3eater program;
diplays the contents of cwd, allows user to make a selection. But I'm having
problems getting it to iterate over a list.
v0.1 03.14.11
by skookie sprite
[email protected]
"""
import curses, curses.wrapper, os, sys
def working_input():
"""the following is demo code to demonstrate my problem... main will accept the following,
but won't accept the product of a directorylist for reasons that I can't figure out."""
dircontents=['this','is','a','list','','and','it','will','iterate','fine','in','the','(main) function.']
return dircontents
def broken_input():
"""this is the code that I NEED to have work... but for reasons beyond me will not iterate in
the main function. It's a simple list of the contents of the CWD."""
cwd=os.getcwd()
dircontents=[]
for item in os.listdir(cwd):
dircontents += [item]
return dircontents
def main(stdscr):
"""This is the program. Designed to take a list of stuff and display it. If I can solve
that hurdle, I'll add selection mechanisms, and break it across screens - amongst other
things. But, currently, it can only accept the demo code. Uncomment one or the other to
see what I mean."""
#broken_input returns an addstr() ERR, but I don't see the difference between working_input
#and broken_input as they are both just lists.
#working_input() is demo code that illustrates my problem
stuffin=working_input()
#stuffin=broken_input()
#the rest of this stuff works. The problem is with the input. Why?
linenumber=int()
linenumber=6
itemnumber=int()
itemnumber=1
stdscr.clear()
stdscr.border(0)
for item in stuffin:
stdscr.addstr(linenumber, 10, '%s - %s' % (itemnumber, item), curses.A_NORMAL)
linenumber += 1
itemnumber += 1
curses.doupdate()
stdscr.getch()
if __name__ == '__main__':
curses.wrapper(main)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您在屏幕上填充了太多内容,因此将越界行号传递给
addstr
。如果您创建一个空目录来运行程序(或放大终端窗口),它就可以工作。要解决此问题,请在
main
中的输出循环之前检查窗口中的行数。You're stuffing too much onto the screen and thus passing an out-of-bounds line number to
addstr
. If you make an empty directory to run the program in (or enlarge your terminal window), it works.To fix this, check the number of lines in the window before the output loop in
main
.在
addstr
之后使用screen.scrollok(1)
允许文本滚动。use
screen.scrollok(1)
afteraddstr
to allow the text to scroll.该问题在
addch
手册页:
给定的程序既不会捕获右下边距的错误(可能应该说“角”),也不会调用
scrollok
允许数据向上滚动。在后一种情况下,您将丢失向上滚动的信息,而处理异常将允许您在显示屏幕的数据后进行提示,然后退出或显示更多数据。The problem is explained in the
addch
manual page:The given program neither catches an error from the lower right margin (probably should say "corner"), nor calls
scrollok
to allow the data to scroll up. In the latter case, you will lose information which is scrolled up, while handling the exception would allow you to prompt after a screen's worth of data is displayed, and then either quit or display more data.