2015-05-15 17 views
10

Vì vậy, tôi đang viết một dự án mà tôi chạy một chương trình liên tục nhận/gửi tin nhắn đến các máy tính khác đang chạy cùng một chương trình.Giữ dòng stdin ở trên cùng hoặc dưới cùng của màn hình thiết bị đầu cuối

Người nhận/người gửi dữ liệu đang chạy trên một chuỗi và in để xuất bản. tôi nhận được những thứ như thế này:

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

Bây giờ vấn đề là đôi khi tôi muốn nhập lệnh vào terminal, vấn đề là khi tôi cố gắng để nhập lệnh và nhắn thông tin mới hoặc MSG REC được in để stdout . Tôi có các lệnh như quitstatus v.v.

>> cho biết dòng đầu vào.

Something như thế này có thể xảy ra:

[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 

Sau đó, tôi sẽ nhấn enter và lệnh status được thi hành nhưng trông rất nghèo trong các thiết bị đầu cuối. Một thông báo xuất hiện sau mỗi 2-4 giây vì vậy đây là một vấn đề. Có cách nào tốt để giải quyết vấn đề này không? Tôi đã thử sử dụng các lệnh con trỏ ANSI để thử và chèn một dòng mới trước dòng cuối cùng vì vậy dòng cuối cùng sẽ luôn là dòng đầu vào và tôi có thể nhập "stat", đợi một lúc và kết thúc bằng "us" mà không có bất kỳ vấn đề.

Tôi cũng thấy mọi người đề nghị curses nhưng cố gắng tích hợp với chương trình của tôi hoàn toàn sai lầm định dạng đầu ra của tôi trong số những thứ khác (và tôi nghĩ rằng nó có lẽ overkill).

Vậy là có một cách dễ dàng để làm cho thread chèn mới MSG REC dòng 1 dòng trên dòng cuối cùng để dòng cuối cùng sẽ luôn luôn vẫn là dòng đầu vào với >> và bất cứ điều gì khác tôi đã gõ trong.

Sử dụng Python2.7 trên Linux.

EDIT: Thay đổi điều đó khiến James Mills trả lời công việc: Tôi đã phải sử dụng điều này bất cứ khi nào chuỗi của tôi đang in một dòng mới.

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 

Trả lời

7

Đây là một ví dụ cơ bản:

Code:

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

này về cơ bản thiết lập một bản demo nguyền rủa ứng dụng mà đòi hỏi user cung đầu vào và hiển thị dấu nhắc tại (24, 0) . Bản demo kết thúc khi người dùng nhập :q. Đối với bất kỳ đầu vào nào khác, nó sẽ thêm đầu vào vào đầu màn hình. Thưởng thức! (<BACKSAPCE> cũng hoạt động!) :)

Xem: curses; tất cả các API tôi đã sử dụng trong ví dụ này là trực tiếp từ thư viện chuẩn này. Trong khi sử dụng lời nguyền có thể hoặc không thể "quá mức" IHMO, tôi khuyên bạn nên sử dụng urwid đặc biệt là nếu sự phức tạp của ứng dụng của bạn bắt đầu phát triển quá mức.

+0

Tôi đã phải thêm 'curses.KEY_BACKSPACE' để sửa các khoảng trống trên máy tính của mình. Ngoài ra điều này không hoạt động như tôi muốn, trong khi chuỗi của tôi đang in các dòng mới mỗi giây (tôi đã chuyển nó 'stdscr' làm đối số và tạo đường toàn cục), nó di chuyển con trỏ đến cuối dòng in Tôi đang gõ ở cuối dòng cuối cùng được in và không phải ở dưới cùng gần '>>>' – Mohammad

+1

Được rồi quản lý để sửa chữa nó và nó bây giờ làm việc như tôi muốn! Tôi chỉ cần thay đổi cách luồng của mình đang in các dòng mới để nó di chuyển con trỏ trở lại vị trí chính xác sau khi in xong. Tôi đã thêm thay đổi vào bài đăng gốc. – Mohammad

+0

Tôi rất vui vì điều này đã giúp bạn giải quyết vấn đề của mình! Sử dụng '' curses.KEY_BACKSPACE'' không hoạt động trên hệ thống của tôi :) –

Các vấn đề liên quan