<p>如评论中所述,使用了<code>curses</code>库</p>
<h2>更新</h2>
<p>输入和输出使用两个子温</p>
<pre class="lang-py prettyprint-override"><code>#!/usr/bin/python3
import curses
from math import acos
from threading import Thread
from random import choice
from time import sleep
from queue import Queue, Empty
commandQueue = Queue()
stdscr = curses.initscr()
stdscr.keypad(True)
upperwin = stdscr.subwin(2, 80, 0, 0)
lowerwin = stdscr.subwin(2,0)
def outputThreadFunc():
outputs = ["So this is another output","Yet another output","Is this even working"] # Just for demo
while True:
upperwin.clear()
upperwin.addstr(f"{choice(outputs)}")
try:
inp = commandQueue.get(timeout=0.1)
if inp == 'exit':
return
else:
upperwin.addch('\n')
upperwin.addstr(inp)
except Empty:
pass
upperwin.refresh()
sleep(1)
def inputThreadFunc():
while True:
global buffer
lowerwin.addstr("->")
command = lowerwin.getstr()
if command:
command = command.decode("utf-8")
commandQueue.put(command)
lowerwin.clear()
lowerwin.refresh()
if command == 'exit':
return
# MAIN CODE
outputThread = Thread(target=outputThreadFunc)
inputThread = Thread(target=inputThreadFunc)
outputThread.start()
inputThread.start()
outputThread.join()
inputThread.join()
stdscr.keypad(False)
curses.endwin()
print("Exit")
</code></pre>
<h2>老办法</h2>
<p>我已经编辑了您的示例,以使用<code>getch</code>而不是<code>input</code></p>
<pre class="lang-py prettyprint-override"><code>#!/usr/bin/python3
import curses
import datetime
from math import acos
from threading import Thread
from random import choice
from time import sleep
from queue import Queue, Empty
INFO_REFRESH_SECONDS = 1
commandQueue = Queue()
buffer = list() # stores your input buffer
stdscr = curses.initscr()
stdscr.keypad(True)
def outputThreadFunc():
outputs = ["So this is another output","Yet another output","Is this even working"] # Just for demo
info = choice(outputs), datetime.datetime.now()
while True:
if datetime.datetime.now() - info[1] > datetime.timedelta(seconds=INFO_REFRESH_SECONDS):
# refresh info after certain period of time
info = choice(outputs), datetime.datetime.now() # timestamp which info was updated
inp = ''
buffer_text = ''.join(buffer)
try:
command = commandQueue.get(timeout=0.1)
if command == 'exit':
return
inp = f"\n{command}"
except Empty:
pass
output_string = f"{info[0]}{inp}\n->{buffer_text}"
stdscr.clear()
stdscr.addstr(output_string)
stdscr.refresh()
if inp:
# to make sure you see the command
sleep(1)
def inputThreadFunc():
while True:
global buffer
# get one character at a time
key = stdscr.getch()
curses.echo()
if chr(key) == '\n':
command = ''.join(buffer)
commandQueue.put(command)
if command == 'exit':
return
buffer = []
elif key == curses.KEY_BACKSPACE:
if buffer:
buffer.pop()
else:
buffer.append(chr(key))
# MAIN CODE
outputThread = Thread(target=outputThreadFunc)
inputThread = Thread(target=inputThreadFunc)
outputThread.start()
inputThread.start()
outputThread.join()
inputThread.join()
stdscr.keypad(False)
curses.endwin()
print("Exit")
</code></pre>