使用ncurses调整终端和滚动问题的大小

时间:2011-01-19 17:54:05

标签: c linux ncurses

我使用ncurses库在C中编程(这是第一次),而且我有两个问题。我在ubuntu上使用默认终端(gnome终端)。

1)我需要调整终端的大小。我使用了resizeter()和resize_term(),但它们都失败了。

2)我使用scrollok()函数,问题是我丢失了滚动的行(当我回到wscrl()时,有空行)。

#include <ncurses.h>

int main() {

WINDOW *win, *win2;

int i;
char c;

initscr();
cbreak();
noecho();

win=newwin(8,20,1,1);
box(win,0,0);
win2=newwin(6,18,2,2);
scrollok(win2,1);
wrefresh(win);
wrefresh(win);

for(i=0;i<15;i++){
    c=wgetch(win2);
    if(c=='u'){
        wscrl(win2,-1);
        wrefresh(win2);
    }
    else{
        wprintw(win2,"%c\n",c);
        wrefresh(win2);
    }
}

delwin(win);
delwin(win2);
endwin();

return 0;
}

3 个答案:

答案 0 :(得分:6)

  1. 您无法从ncurses调整终端窗口的大小。您提到的功能调整了curses绘制的终端窗口部分的大小。当用户从应用程序外部调整窗口 (可能使用鼠标)时,您的想法是捕获SIGWINCH信号并在处理程序中调用resizeterm

  2. 这是预期的行为,虽然在ncurses和Unix标准/ POSIX中记录不足。 NetBSD's curses docs明确说明:

      

    如果 n 为正,那么stdscr   向上滚动 n 行丢失了   从stdscr的顶部和 n 空白   线条插在底部。如果    n 为负数,然后stdscr向下滚动。 n 空行是   插入stdscr的顶部和    n 行从底部丢失。

    因此,您必须手动保存输入并在滚动时重新打印。

答案 1 :(得分:2)

POSIX不包括这种情况,因为curses文档不是POSIX的一部分。 Open Group恰好维护两者的文档:

正如resizeterm的手册页中所述,您不应该在信号处理程序中调用该函数,因为它调用“不安全”函数。在几个地方讨论了“不安全”功能的主题;在gcc的documentation中会有一个开始。

关于文档,@larsmans似乎是引用scroll(3),但没有引用ncurses和“POSIX”的类似链接。对于它的价值:

  • ncurses(似乎解决了暗示NetBSD独有的观点)
  • X/Open(必须更通用,因为它旨在涵盖不同的实现)

回到OP的问题:

  1. 示例程序未显示OP使用resizetermresize_term。没有说明,但可能是OP调整了终端窗口的大小并且程序没有响应。 resizeterm的手册页很清楚,ncurses不会导致终端调整大小。对于那个(在某些终端上),可以使用resize-s选项(xterm的实用程序)。如果成功,则会调整终端的大小,终端会发送SIGWINCH。 ncurses有一个预定义的信号处理程序,但在应用程序级别,建议处理KEY_RESIZEncurses-examples中有几个程序可以执行此操作。
  2. 在窗口中移动向上行必然会移动窗口的 out 。这意味着行将移动到窗口中以替换已离开的那些行。 “窗口”就是:有限大小的数据视图。对于不同大小的视图,建议开发人员使用“pad”(参见manual page)。滚动手册页中的注释提到了空白颜色(替换线)的一些问题。应用程序是否将替换留空或填入应用程序的数据取决于应用程序。 Curses不会自动执行此操作(甚至不适用于打击垫)。

答案 2 :(得分:0)

您无法从ncurses调整终端窗口的大小,但您可以调整resize系统调用的终端的大小。

#include <ncurses.h>
#include <stdlib.h>

int main(int argc, char *argv[]){
    WINDOW *ventana1;
    system("resize -s 30 80");
    initscr();
    start_color();
    ventana1 = newwin(15, 50, 0, 0);
    init_pair(1,COLOR_YELLOW,COLOR_BLUE);
    init_pair(2,COLOR_BLUE, COLOR_YELLOW);
    wbkgd(ventana1,COLOR_PAIR(1));
    wprintw(ventana1, "POLLO");
    wrefresh(ventana1);
    wgetch(ventana1);
    wgetch(ventana1);
    system("resize -s 20 60");
    wbkgd(ventana1,COLOR_PAIR(2));
    wprintw(ventana1, "POLLO");
    wrefresh(ventana1);
    wgetch(ventana1);
    wgetch(ventana1);
    system("resize -s 35 85");
    system("clear");
    wbkgd(ventana1,COLOR_PAIR(1));
    wprintw(ventana1, "POLLO");
    wrefresh(ventana1);
    wgetch(ventana1);
    wgetch(ventana1);
    delwin(ventana1);
    endwin();
    system("resize -s 25 75");
}