如果未先刷新 stdscr,则不会显示 Python 诅咒的 newwin

问题描述

我目前正在玩诅咒并试图了解一切的反应。我以为我正在取得进步,直到我偶然发现了这段简单的代码

import curses

def main(stdscr: curses.window) -> None:
    stdscr.addstr(0,"A")
    # stdscr.refresh()

    win = curses.newwin(2,2,1,0)
    win.addstr(0,"B")
    win.refresh()
    stdscr.getch()
    
curses.wrapper(main)

这里我不明白的是为什么结果是一个只有 A 而没有 B 的屏幕。我还发现有趣的是,如果我取消注释注释行,我会同时得到 A 和 B。

有人能解释一下发生了什么吗,或者至少给我指出一些解释它的文档。

提前致谢!

解决方法

“B”实际上写入终端,但在为刷新完成的重绘中立即被覆盖,作为 stdscr.getch() 的副作用。手册页说 getch 这样做:

如果窗口不是一个pad,并且它已经被移动或修改过 最后调用 wrefreshwrefresh 将在另一个字符之前调用 已读。

初始化curses 会在第一次绘制时清除stdscr。同样,在手册页中(对于 initscr):

initscr 也会导致第一次调用 refresh(3x) 清除屏幕。

我使用实用程序 (unmap) 生成此列表,该实用程序使所有内容都可读(实际上 空格 未转换),将输出带到终端使用 script(并将显示限制为 5x5 屏幕):

Script started on 2021-04-09 19:08:24-04:00 [TERM="screen.xterm-new" TTY="/dev/pts/0" COLUMNS="80" LINES="40"]
\n
\E[?1049h
\E[22;0;0t
\E[1;5r
\E(B
\E[m
\E[4l
\E[?7h
\E[?1h
\E=
\E[39;49m
\E[39;49m
\E[37m
\E[40m
\E[1;1H     
\E[2;1H     
\E[3;1H     
\E[4;1H     
\E[5;1H    
\E[?7l 
\E[?7h
\E[H
\E[2dB
\E[39;49m
\E[37m
\E[40m
\E[H     
\E[2;1H     
\E[3;1H     
\E[4;1H     
\E[5;1H    
\E[?7l 
\E[?7h
\E[HA
\E[?1l
\E>
\E[39;49m\r
\E[5d
\E[K
\E[5;1H
\E[?1049l
\E[23;0;0t\r
\E[?1l
\E>
\nScript done on 2021-04-09 19:08:24-04:00 [COMMAND_EXIT_CODE="0"]
\n

“B”出现在这一行:

\E[2dB

和“A”:

\E[HA

(其他字符是转义序列的一部分)。

取消注释该行即可完成 initscr 所需的重绘,并且 {{{} 中不需要 stdscr 1}} 调用(因此新窗口不会被覆盖)。