使用python curses

时间:2015-06-12 04:09:49

标签: python scroll curses

使用python curses我试图在窗口中写入一些文本。 但当我到达窗口的尽头时,我得到addstr() returned ERR

如何逐页或逐行滚动输出。如何绑定SPACE键或向下箭头?

这是我的代码:

try:
    screen = curses.initscr()
    screen.immedok(True)
    curses.start_color()
    curses.init_pair(1, curses.COLOR_GREEN, curses.COLOR_BLACK)
    curses.init_pair(2, curses.COLOR_WHITE, curses.COLOR_BLACK)
    screen.bkgd(curses.color_pair(2))
    screen.scrollok(1)
    screen.border(0)

    p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    (output, err) = p.communicate()
    linenumber = 1
    for line in getline(output):
        if linenumber <= 2:
            # First two lines are header, mark bold
            screen.addstr(linenumber, 2, line, curses.color_pair(1)|curses.A_BOLD)
        else:
            screen.addstr(linenumber, 2, line)
        linenumber += 1

   screen.getch()
   curses.endwin()

except Exception, e:
    print "\n\033[1;91m[FAILED]\033[0m  Interrupt  ", e
    logging.error(e, exc_info=True)
    curses.endwin()

2 个答案:

答案 0 :(得分:2)

问题是,您对screen.addstr的来电要求在屏幕末尾显示行号。考虑到您在屏幕上绘制的框,更好的方法是在框内创建一个新窗口(例如使用curses.newwin)并在该窗口中编写addstr个调用。

您的示例未按给定编译。这是一个有效的例子:

import curses
import logging
import subprocess
import sys

command = "ls -l /bin"
try:
    screen = curses.initscr()
    screen.immedok(True)
    curses.start_color()
    curses.init_pair(1, curses.COLOR_GREEN, curses.COLOR_BLACK)
    curses.init_pair(2, curses.COLOR_WHITE, curses.COLOR_BLACK)
    screen.bkgd(curses.color_pair(2))
    screen.border(0)
    boxed = curses.newwin(curses.LINES - 2, curses.COLS - 2, 1, 1)
    boxed.scrollok(1)

    p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    (output, err) = p.communicate()
    linenumber = 1
    for line in output.split("\n"):
        if linenumber <= 2:
            # First two lines are header, mark bold
            boxed.addstr(line, curses.color_pair(1)|curses.A_BOLD)
        else:
            boxed.addstr(line)
        boxed.addch("\n")
        linenumber += 1
        boxed.getch()

    screen.getch()
    curses.endwin()

except Exception, e:
    print "\n\033[1;91m[FAILED]\033[0m  Interrupt  ", e
    logging.error(e, exc_info=True)

答案 1 :(得分:2)

这是答案:How to make a scrolling menu in python-curses

此代码允许您从字符串列表中创建一个小菜单。
您还可以使用此代码从sqlite查询或csv文件中获取字符串列表。
要编辑菜单的最大行数,您只需编辑max_row即可。
如果按Enter键,程序将打印所选字符串值及其位置。

from __future__ import division  #You don't need this in Python3
import curses
from math import *



screen = curses.initscr()
curses.noecho()
curses.cbreak()
curses.start_color()
screen.keypad( 1 )
curses.init_pair(1,curses.COLOR_BLACK, curses.COLOR_CYAN)
highlightText = curses.color_pair( 1 )
normalText = curses.A_NORMAL
screen.border( 0 )
curses.curs_set( 0 )
max_row = 10 #max number of rows
box = curses.newwin( max_row + 2, 64, 1, 1 )
box.box()


strings = [ "a", "b", "c", "d", "e", "f", "g", "h", "i", "l", "m", "n" ] #list of strings
row_num = len( strings )

pages = int( ceil( row_num / max_row ) )
position = 1
page = 1
for i in range( 1, max_row + 1 ):
    if row_num == 0:
        box.addstr( 1, 1, "There aren't strings", highlightText )
    else:
        if (i == position):
            box.addstr( i, 2, str( i ) + " - " + strings[ i - 1 ], highlightText )
        else:
            box.addstr( i, 2, str( i ) + " - " + strings[ i - 1 ], normalText )
        if i == row_num:
            break

screen.refresh()
box.refresh()

x = screen.getch()
while x != 27:
    if x == curses.KEY_DOWN:
        if page == 1:
            if position < i:
                position = position + 1
            else:
                if pages > 1:
                    page = page + 1
                    position = 1 + ( max_row * ( page - 1 ) )
        elif page == pages:
            if position < row_num:
                position = position + 1
        else:
            if position < max_row + ( max_row * ( page - 1 ) ):
                position = position + 1
            else:
                page = page + 1
                position = 1 + ( max_row * ( page - 1 ) )
    if x == curses.KEY_UP:
        if page == 1:
            if position > 1:
                position = position - 1
        else:
            if position > ( 1 + ( max_row * ( page - 1 ) ) ):
                position = position - 1
            else:
                page = page - 1
                position = max_row + ( max_row * ( page - 1 ) )
    if x == curses.KEY_LEFT:
        if page > 1:
            page = page - 1
            position = 1 + ( max_row * ( page - 1 ) )

    if x == curses.KEY_RIGHT:
        if page < pages:
            page = page + 1
            position = ( 1 + ( max_row * ( page - 1 ) ) )
    if x == ord( "\n" ) and row_num != 0:
        screen.erase()
        screen.border( 0 )
        screen.addstr( 14, 3, "YOU HAVE PRESSED '" + strings[ position - 1 ] + "' ON POSITION " + str( position ) )

    box.erase()
    screen.border( 0 )
    box.border( 0 )

    for i in range( 1 + ( max_row * ( page - 1 ) ), max_row + 1 + ( max_row * ( page - 1 ) ) ):
        if row_num == 0:
            box.addstr( 1, 1, "There aren't strings",  highlightText )
        else:
            if ( i + ( max_row * ( page - 1 ) ) == position + ( max_row * ( page - 1 ) ) ):
                box.addstr( i - ( max_row * ( page - 1 ) ), 2, str( i ) + " - " + strings[ i - 1 ], highlightText )
            else:
                box.addstr( i - ( max_row * ( page - 1 ) ), 2, str( i ) + " - " + strings[ i - 1 ], normalText )
            if i == row_num:
                break



    screen.refresh()
    box.refresh()
    x = screen.getch()

curses.endwin()
exit()

Screenshot of the code