2015-05-15 46 views
10

所以我寫,我運行一個不斷接收/發送消息到運行相同程序的其它計算機程序的項目。保持標準輸入線在終端屏幕的頂部或底部

接收機/數據的發送方是在一個線程並打印到標準輸出運行。 我得到的東西是這樣的:

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

現在的問題是,有時我想輸入命令到終端,問題是,當我嘗試輸入命令和新信息的消息或MSG REC打印到stdout 。我有諸如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光標指令,試圖在最後一行前插入新行,以便最後一行將始終保持爲輸入線,我可以輸入「統計」,等待一會兒,並用「我們」沒有任何完成它的問題。

我也看到有人推薦curses,但試圖將其與我的程序集成完全搞亂了我的輸出格式和其他東西(我認爲它的矯枉過正也許)。

那麼,有沒有一種簡單的方法,以使線程插入新MSG REC線1號線的最後一行的上方,最後一行將永遠留我在輸入與輸入線>>和任何其他。

在Linux上使用Python2.7。

編輯:變化是由詹姆斯·米爾斯回答工作: 我不得不使用這個每當我的線程打印新的生產線。

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 

回答

7

這裏是一個基本例如:

代碼:

#!/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) 

這基本上設置一個演示詛咒應用程序,它提示用戶輸入和顯示在(24, 0)提示。演示終止於用戶輸入:q。對於任何其他輸入,它將輸入追加到屏幕的頂部。請享用! (<BACKSAPCE>也適用!):)

參見:curses;我在這個例子中使用的所有API都是直接來自這個標準庫。雖然使用詛咒可能會或可能不會「過度」IHMO我會建議使用urwid,特別是如果您的應用程序的複雜性開始超出普通的詛咒。

+0

我不得不添加'curses.KEY_BACKSPACE'來解決我的機器上退格。 此外,這不工作,因爲我希望它,而我的線程是每秒打印新行(我通過它'stdscr'作爲參數,使行全局),它將光標移動到打印行的結尾,所以什麼我正在輸入的是最後一行的結尾處,而不是在'>>>' – Mohammad

+1

附近的底部。好吧設法修復它,現在它正在按照我的要求工作! 我只是改變了我的線程打印新行的方式,以便在完成打印後將光標移回到正確的位置。 我將變更添加到原始帖子。 – Mohammad

+0

我很高興這有助於你解決你的問題!使用''curses.KEY_BACKSPACE''在我的系統上不起作用:) –