我开始学习Python中的curses。我在Mac OS X上使用Python 3.5。当我尝试在右下角写入时,程序崩溃并出现以下错误:
$ python ex_curses.py
[...]
File "ex_curses.py", line 19, in do_curses
screen.addch(mlines, mcols, 'c')
_curses.error: add_wch() returned ERR
示例程序是:
import curses
def do_curses(screen):
curses.noecho()
curses.curs_set(0)
screen.keypad(1)
(line, col) = 12, 0
screen.addstr(line, col, "Hello world!")
line += 1
screen.addstr(line, col, "Hello world!", curses.A_REVERSE)
screen.addch(0, 0, "c")
(mlines, mcols) = screen.getmaxyx()
mlines -= 1
mcols -= 1
screen.addch(mlines, mcols, 'c')
while True:
event = screen.getch()
if event == ord("q"):
break
curses.endwin()
if __name__ == "__main__":
curses.wrapper(do_curses)
我有一种感觉,我错过了一些明显的东西,但我不知道是什么。
答案 0 :(得分:4)
这是预期的行为(怪癖),因为addch
在添加字符后尝试换行到下一行。有comment in lib_addch.c处理此问题:
/*
* The _WRAPPED flag is useful only for telling an application that we've just
* wrapped the cursor. We don't do anything with this flag except set it when
* wrapping, and clear it whenever we move the cursor. If we try to wrap at
* the lower-right corner of a window, we cannot move the cursor (since that
* wouldn't be legal). So we return an error (which is what SVr4 does).
* Unlike SVr4, we can successfully add a character to the lower-right corner
* (Solaris 2.6 does this also, however).
*/
答案 1 :(得分:3)
为未来的读者。在@Thomas Dickey回答之后,我在代码中添加了以下代码段。
try:
screen.addch(mlines, mcols, 'c')
except _curses.error as e:
pass
现在我的代码如下:
import curses
import _curses
def do_curses(screen):
curses.noecho()
curses.curs_set(0)
screen.keypad(1)
(line, col) = 12, 0
screen.addstr(line, col, "Hello world!")
line += 1
screen.addstr(line, col, "Hello world!", curses.A_REVERSE)
screen.addch(0, 0, "c")
(mlines, mcols) = screen.getmaxyx()
mlines -= 1
mcols -= 1
try:
screen.addch(mlines, mcols, 'c')
except _curses.error as e:
pass
while True:
event = screen.getch()
if event == ord("q"):
break
curses.endwin()
if __name__ == "__main__":
curses.wrapper(do_curses)
答案 2 :(得分:1)
window.insch(...)
可以在窗口的右下方放置一个字符,而无需前进光标。该位置上的任何字符都会在不引起错误的情况下向右碰撞。
答案 3 :(得分:0)
这是一种奇异的解决方案,它利用了curses
实际上可以在绘制边框时绘制右下角的字符(而不会引发异常)的事实。查看完整的示例:
# -*- coding: utf-8 -*-
import curses
def addch_bottom_right(window, ch):
"""
Somehow, the underlying ncurses library has an issue
with writing a char into bottom-right corner
(see the https://stackoverflow.com/a/36389161 for example).
But we can use the workaround:
- create a subwindow 1x1 of the current window in the bottom-right corner
- draw a border of that window, consisting only of the desired character:
for a 1x1 window, that border will consist exclusively of this single character.
- refresh the screen to show your new 'window' with the 'border'.
"""
print("Putting char '%s' in the bottom-right corner" % ch)
beg_y, beg_x = window.getbegyx()
max_y, max_x = window.getmaxyx()
br_y = beg_y + max_y - 1
br_x = beg_x + max_x - 1
print('Coordinates of current window: %sx%s' % (br_y, br_x))
w = window.subwin(1, 1, br_y, br_x)
# only 'br' (bottom-right corner) gets printed for 1x1 box
w.border(*([ch] * 8))
w.noutrefresh()
window.noutrefresh()
curses.doupdate()
def demo(screen, show_border=True):
"""
Try the workaround with three different windows nesting levels.
Borders drawn here only to show where the windows are.
"""
curses.curs_set(0)
w = screen.subwin(8, 8, 10, 10)
if show_border:
w.border()
addch_bottom_right(w, 'Window'[0])
w2 = w.subwin(3, 3, 12, 12)
if show_border:
w2.box()
addch_bottom_right(w2, 'Subwindow'[0])
addch_bottom_right(screen, 'Main screen'[0])
screen.getch()
if __name__ == '__main__':
curses.wrapper(demo)