Perl curses:refresh()不会删除行

时间:2015-02-16 06:17:13

标签: perl ncurses curses

sub display {
    my @data = @_;
    my $max_row = 0;
    my $max_col = 0;
    getmaxyx($max_row, $max_col);
    clear();                        <------ i dont want to clear everytime

    if ($start_display) {
        my $row   = 0;
        my $color = COLOR_PAIR(1);
        attron($color);

        attroff($color);
        foreach my $line (@data) {
            $color = COLOR_PAIR(1);
            $color = COLOR_PAIR(2) if ($line =~ /waiting/);
            attron($color);
            $line = substr($line, 0, $max_col);
            addstr($row++, 0, $line);
            attroff($color);
            last if ($row >= $max_row - 1);
        }
        $color = COLOR_PAIR(1);
        attron($color);
        attroff($color);
    } else {
        my $dots = '.';
        $dots = $dots x $dot_cnt;
        addstr("Program is starting...$dots");
        $dot_cnt++;
        sleep 1;
    }

    my $color = COLOR_PAIR(1);
    attron($color);
    addstr($max_row-1, 0, $usage);
    attroff($color);

    refresh();     <------ refreshes but doesnt clear 
} ## end sub display

现在,我每次都在清屏,但这会让屏幕变得非常不稳定。如果我摆脱了clear(),那么昙花一现,但refresh()没有正确更新(即保留以前显示的行,当某些行被删除时)

如何正确更新屏幕以便只更改更改的行并从屏幕上正确删除行?

1 个答案:

答案 0 :(得分:1)

addstr()只会写入传递给它的字符串的长度。为了避免残留,您需要确保将字符串填充到窗口的宽度。我建议在截断为$max_col的步骤中用空格填充字符串:

$line = substr( $line . " " x $max_col, 0, $max_col );

或者将其排除在外:

sub addstr_pad { 
    my ( $row, $str, $width ) = @_;
    addstr( $row, 0, substr( $str . " " x $width, 0, $width ) ); 
}
...
addstr_pad( $row++, $line, $max_col );

为了确保您清除上次迭代中可能包含文本的任何行,请在迭代@data后包含此内容:

while( $row <= $max_row ) { 
    addstr( $row++, 0, " " x $max_col )); 
}

如果$max_row的长度保留在上次运行中,则您无需清除@data