将 stdin 行保留在终端屏幕的顶部或底部
Keep stdin line at top or bottom of terminal screen
所以我正在编写一个项目,其中我 运行 一个程序不断 receives/sends 向其他计算机 运行 发送消息 运行 同一个程序。
receiver/sender 数据在线程上 运行 并打印到标准输出。
我得到这样的东西:
[INFO] User 'blah' wants to send message to you.
[INFO] some other info
[MSG REC] Message 'hello' received from blah.
现在的问题是,有时我希望在终端中输入命令,问题是当我尝试输入命令时,新的信息消息或 MSG REC
被打印到标准输出。我有 quit
和 status
等命令
>> 表示输入行。
可能会发生这样的事情:
[INFO] User 'blah' wants to send message to you.
[INFO] some other info
[MSG REC] Message 'hello' received from blah.
>> stat[MSG REC] Message 'sup' received from Bob.
us
然后我会按回车键并执行命令 status
但在终端中看起来很差。每 2-4 秒出现一条消息,因此这是一个问题。有解决这个问题的好方法吗?我尝试使用 ANSI 游标命令尝试在最后一行之前插入一个新行,这样最后一行将始终保留为输入行,我可以输入 "stat",稍等片刻,然后用 "us" 没有任何问题。
我也看到有人推荐 curses
但试图将其与我的程序集成完全弄乱了我的输出格式等(我认为它可能有点过头了)。
那么有没有一种简单的方法可以让线程在最后一行上方插入新的 MSG REC
行 1 行,这样最后一行将始终作为输入行保留 >> 以及我输入的任何其他内容.
在 Linux.
上使用 Python2.7
编辑:让 James Mills 回答有效的更改:
每当我的线程打印新行时,我都必须使用它。
myY, myX = stdscr.getyx();
str = "blah blah"; #my message I want to print
stdscr.addstr(len(lines), 0, str)
lines.append(str)
stdscr.move(myY, myX) #move cursor back to proper position
这是一个基本示例:
代码:
#!/usr/bin/env python
from string import printable
from curses import erasechar, wrapper
PRINTABLE = map(ord, printable)
def input(stdscr):
ERASE = input.ERASE = getattr(input, "ERASE", ord(erasechar()))
Y, X = stdscr.getyx()
s = []
while True:
c = stdscr.getch()
if c in (13, 10):
break
elif c == ERASE:
y, x = stdscr.getyx()
if x > X:
del s[-1]
stdscr.move(y, (x - 1))
stdscr.clrtoeol()
stdscr.refresh()
elif c in PRINTABLE:
s.append(chr(c))
stdscr.addch(c)
return "".join(s)
def prompt(stdscr, y, x, prompt=">>> "):
stdscr.move(y, x)
stdscr.clrtoeol()
stdscr.addstr(y, x, prompt)
return input(stdscr)
def main(stdscr):
Y, X = stdscr.getmaxyx()
lines = []
max_lines = (Y - 3)
stdscr.clear()
while True:
s = prompt(stdscr, (Y - 1), 0) # noqa
if s == ":q":
break
# scroll
if len(lines) > max_lines:
lines = lines[1:]
stdscr.clear()
for i, line in enumerate(lines):
stdscr.addstr(i, 0, line)
stdscr.addstr(len(lines), 0, s)
lines.append(s)
stdscr.refresh()
wrapper(main)
这基本上设置了一个演示 curses 应用程序,提示用户输入并在 (24, 0)
处显示提示。演示在用户输入 :q
时终止。对于任何其他输入,它将输入附加到屏幕顶部。享受! (<BACKSAPCE>
也有效!):)
参见:curses; all of the API I used in this example is straight from this standard library. Whilst using curses may or may not be "overkill" IHMO I would recommend the use of urwid 尤其是当您的应用程序的复杂性开始超出普通的诅咒时。
所以我正在编写一个项目,其中我 运行 一个程序不断 receives/sends 向其他计算机 运行 发送消息 运行 同一个程序。
receiver/sender 数据在线程上 运行 并打印到标准输出。 我得到这样的东西:
[INFO] User 'blah' wants to send message to you.
[INFO] some other info
[MSG REC] Message 'hello' received from blah.
现在的问题是,有时我希望在终端中输入命令,问题是当我尝试输入命令时,新的信息消息或 MSG REC
被打印到标准输出。我有 quit
和 status
等命令
>> 表示输入行。
可能会发生这样的事情:
[INFO] User 'blah' wants to send message to you.
[INFO] some other info
[MSG REC] Message 'hello' received from blah.
>> stat[MSG REC] Message 'sup' received from Bob.
us
然后我会按回车键并执行命令 status
但在终端中看起来很差。每 2-4 秒出现一条消息,因此这是一个问题。有解决这个问题的好方法吗?我尝试使用 ANSI 游标命令尝试在最后一行之前插入一个新行,这样最后一行将始终保留为输入行,我可以输入 "stat",稍等片刻,然后用 "us" 没有任何问题。
我也看到有人推荐 curses
但试图将其与我的程序集成完全弄乱了我的输出格式等(我认为它可能有点过头了)。
那么有没有一种简单的方法可以让线程在最后一行上方插入新的 MSG REC
行 1 行,这样最后一行将始终作为输入行保留 >> 以及我输入的任何其他内容.
在 Linux.
上使用 Python2.7编辑:让 James Mills 回答有效的更改: 每当我的线程打印新行时,我都必须使用它。
myY, myX = stdscr.getyx();
str = "blah blah"; #my message I want to print
stdscr.addstr(len(lines), 0, str)
lines.append(str)
stdscr.move(myY, myX) #move cursor back to proper position
这是一个基本示例:
代码:
#!/usr/bin/env python
from string import printable
from curses import erasechar, wrapper
PRINTABLE = map(ord, printable)
def input(stdscr):
ERASE = input.ERASE = getattr(input, "ERASE", ord(erasechar()))
Y, X = stdscr.getyx()
s = []
while True:
c = stdscr.getch()
if c in (13, 10):
break
elif c == ERASE:
y, x = stdscr.getyx()
if x > X:
del s[-1]
stdscr.move(y, (x - 1))
stdscr.clrtoeol()
stdscr.refresh()
elif c in PRINTABLE:
s.append(chr(c))
stdscr.addch(c)
return "".join(s)
def prompt(stdscr, y, x, prompt=">>> "):
stdscr.move(y, x)
stdscr.clrtoeol()
stdscr.addstr(y, x, prompt)
return input(stdscr)
def main(stdscr):
Y, X = stdscr.getmaxyx()
lines = []
max_lines = (Y - 3)
stdscr.clear()
while True:
s = prompt(stdscr, (Y - 1), 0) # noqa
if s == ":q":
break
# scroll
if len(lines) > max_lines:
lines = lines[1:]
stdscr.clear()
for i, line in enumerate(lines):
stdscr.addstr(i, 0, line)
stdscr.addstr(len(lines), 0, s)
lines.append(s)
stdscr.refresh()
wrapper(main)
这基本上设置了一个演示 curses 应用程序,提示用户输入并在 (24, 0)
处显示提示。演示在用户输入 :q
时终止。对于任何其他输入,它将输入附加到屏幕顶部。享受! (<BACKSAPCE>
也有效!):)
参见:curses; all of the API I used in this example is straight from this standard library. Whilst using curses may or may not be "overkill" IHMO I would recommend the use of urwid 尤其是当您的应用程序的复杂性开始超出普通的诅咒时。