python - 将 stdin 行保留在终端屏幕的顶部或底部

标签 python terminal curses

所以我正在编写一个项目,我在其中运行一个程序,该程序不断地向运行相同程序的其他计算机接收/发送消息。

数据的接收者/发送者在线程上运行并打印到标准输出。 我得到这样的东西:

[INFO] User 'blah' wants to send message to you.
[INFO] some other info
[MSG REC] Message 'hello' received from blah.

现在的问题是,有时我希望在终端中输入命令,问题是当我尝试输入命令时,新的信息消息或 MSG REC 被打印到标准输出。我有诸如 quitstatus 等命令

>>表示输入行。

可能会发生这样的事情:

[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,但试图将其与我的程序集成完全弄乱了我的输出格式以及其他东西(我认为它可能有点矫枉过正)。

那么有没有一种简单的方法可以让线程在最后一行上方的第 1 行插入新的 MSG REC 行,这样最后一行将始终保留为 >> 以及我拥有的任何其他内容的输入行输入。

在 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 ;我在这个例子中使用的所有 API 都直接来自这个标准库。虽然使用诅咒可能会或可能不会“过度杀伤” IHMO,但我建议使用 urwid尤其是当您的应用程序的复杂性开始超出普通的“ol curses”时。

关于python - 将 stdin 行保留在终端屏幕的顶部或底部,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30258999/

相关文章:

python - 填写每小时的事件时间 - Python

ssh - 通过代理与 SSH 连接

bash - sed 从文件中删除第一行

python-3.x - 如何扩展Python3中的curses窗口类?

python - 使用python将对象输出到文件

python - 在 python 2.7 中添加字节

python - 未排序列表的二分查找

linux - 在 Linux 中为多个文件运行可执行终端程序以生成多个输出文件

Python 在不清除屏幕的情况下诅咒 iniscr()?

python - 同时使用调试器和 curses?