2011-07-27 39 views
17

Tôi biết có thể ghi đè dòng cuối cùng được hiển thị trong thiết bị đầu cuối bằng "\ r", nhưng tôi đang gặp khó khăn trong việc tìm ra nếu có cách quay lại và chỉnh sửa trước đó dòng được in trong bảng điều khiển.Python - Viết lại nhiều dòng trong Bảng điều khiển

Điều tôi muốn làm là in lại nhiều dòng cho RPG dựa trên văn bản, tuy nhiên một người bạn cũng thắc mắc về ứng dụng này có một dòng dành riêng cho thanh tiến trình và một dòng mô tả tải xuống.

tức là giao diện điều khiển sẽ in:

tập tin Di chuyển: NameOfFile.txt
Tổng Progress: [########] 40%

và sau đó cập nhật một cách thích hợp (cho cả hai dòng) khi chương trình đang chạy.

+1

nền tảng là gì này nghĩa vụ phải được trên? –

+0

Unix, đặc biệt là Fuduntu, nhưng tôi muốn nó hoạt động trên hầu hết các nền tảng ... Không cần phải là mặc dù. – JRJurman

+0

http://stackoverflow.com/questions/3002085/python-to-print-out-status-bar-and-percentage câu trả lời hay ở đó, đã giúp tôi tải! –

Trả lời

28

Trên Unix, sử dụng mô-đun curses.

Trên Windows, có một số lựa chọn:

dụ đơn giản sử dụng lời nguyền (Tôi là tổng số lời nguyền n00b):

import curses 
import time 

def report_progress(filename, progress): 
    """progress: 0-10""" 
    stdscr.addstr(0, 0, "Moving file: {0}".format(filename)) 
    stdscr.addstr(1, 0, "Total progress: [{1:10}] {0}%".format(progress * 10, "#" * progress)) 
    stdscr.refresh() 

if __name__ == "__main__": 
    stdscr = curses.initscr() 
    curses.noecho() 
    curses.cbreak() 

    try: 
     for i in range(10): 
      report_progress("file_{0}.txt".format(i), i+1) 
      time.sleep(0.5) 
    finally: 
     curses.echo() 
     curses.nocbreak() 
     curses.endwin() 
+0

Cảm ơn, tôi đã thêm liên kết vào câu trả lời. API có giống như Unix không? – codeape

+1

Có một mô-đun để thực hiện những gì bạn muốn: [progressbar] [http://code.google.com/p/python-progressbar/] –

+0

Vâng, nhưng cách hiển thị các hàng trạng thái không ở đầu màn hình, nhưng tại đáy (trên dòng tiếp theo sau đầu ra trước đó). Tôi muốn một hiệu ứng như với nhiều 'pv --name' trong một đường ống –

2

Cuối cùng, nếu bạn muốn thao tác màn hình, bạn cần phải sử dụng các thư viện hệ điều hành cơ bản, mà thường sẽ là:

  • lời nguyền (hoặc mã kiểm soát thiết bị đầu cuối cơ bản như theo dõi bởi các terminfo/cơ sở dữ liệu termcap) trên Linux hoặc OSX
  • API bảng điều khiển win32 trên Windows.

Câu trả lời từ @codeape đã cung cấp cho bạn một số tùy chọn nếu bạn không ngại gắn bó với một hệ điều hành hoặc sẵn lòng cài đặt thư viện của bên thứ ba trên Windows.

Tuy nhiên, nếu bạn muốn có giải pháp đa nền tảng mà bạn có thể chỉ cần cài đặt pip, bạn có thể sử dụng asciimatics. Là một phần của việc phát triển gói này, tôi đã phải giải quyết sự khác biệt giữa các môi trường để cung cấp một API duy nhất hoạt động trên Linux, OSX và Windows.

Đối với thanh tiến trình, bạn có thể sử dụng đối tượng BarChart như được hiển thị trong this demo sử dụng this code.

+1

Tôi phần nào ngạc nhiên rằng hữu ích như một thao tác trên nền tảng giao diện điều khiển không được vận chuyển với python. (Esp. Cho sự tồn tại của Tkinter) – PythonNut

+1

@PythonNut - Tôi không biết lịch sử đầy đủ, nhưng AFAIK không ai sẵn sàng viết một hỗ trợ API tương thích cho Windows và do đó [khuyến cáo] (https: // tài liệu. python.org/3/howto/curses.html) là sử dụng các tùy chọn mã keo khác nhau đã được đề cập. –

1

Đây là một mô-đun Python cho cả Python 2/3, mà chỉ đơn giản có thể giải quyết tình huống như vậy với một vài dòng mã; D

reprint - A simple module for Python 2/3 to print and refresh multi line output contents in terminal

Bạn chỉ có thể điều trị mà output dụ như một bình thường dict hoặc list (phụ thuộc vào chế độ bạn sử dụng).Khi bạn sửa đổi nội dung trong output dụ, sản lượng trong thiết bị đầu cuối sẽ tự động làm mới: D

Đối với nhu cầu của bạn, đây là mã:

from reprint import output 
import time 

if __name__ == "__main__": 
    with output(output_type='dict') as output_lines: 
     for i in range(10): 
      output_lines['Moving file'] = "File_{}".format(i) 
      for progress in range(100): 
       output_lines['Total Progress'] = "[{done}{padding}] {percent}%".format(
        done = "#" * int(progress/10), 
        padding = " " * (10 - int(progress/10)), 
        percent = progress 
        ) 
       time.sleep(0.05) 
+0

Khi tôi thử 'output_lines ['one'] = 'abcd'', sau khi thiết lập nó giống như bạn đã làm, tôi nhận được một lỗi phân chia bằng không. Tôi tin rằng có cái gì đó sai ở đây. Bạn có hiểu biết gì về điều đó không? – cat40

+0

@ cat40 Tôi nghĩ rằng có lẽ một cái gì đó làm cho 'get_terminal_size()' trả về một giá trị (0,0). Tôi có thể yêu cầu thêm chi tiết cho điều đó không? Bạn có thể đăng nó tại vấn đề Github: D – Yinzo

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