Perl 诅咒:refresh() 不删除行

Perl curses: refresh() doesnt delete lines

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() 不会正确更新(即保留之前显示的行,当一些应该被删除时)

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

addstr() 只会写入传递给它的字符串的长度。为了避免残留,您需要确保将字符串填充到 window 的宽度。我建议在 t运行cate 到 $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 )); 
}

如果 @data 的长度从之前的 运行 中保留下来,则您不一定需要通过 $max_row 清除。