【问题标题】:Resize terminal and scrolling problem with ncurses使用 ncurses 调整终端大小和滚动问题
【发布时间】:2011-01-19 17:54:04
【问题描述】:

我正在使用 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;
}

【问题讨论】:

  • 我认为你的意思是调整终端的大小,而不是调整外壳的大小。大多数终端不允许转义序列调整它们的大小,因为这会让用户非常恼火。
  • @R.. 呸,至少调整终端模拟器的大小不会像调整 物理 终端那样烦人。

标签: c linux ncurses


【解决方案1】:
  1. 您无法通过 ncurses 调整终端窗口的大小。您提到的功能调整了由诅咒绘制的终端窗口部分的大小。这个想法是,当用户从应用程序外部(可能使用鼠标)调整窗口大小时,您捕获SIGWINCH 信号并在处理程序中调用resizeterm

  2. 这是预期的行为,尽管在 ncurses 和 Unix 标准/POSIX 中的记录很少。 NetBSD's curses docs 明确声明:

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

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

【讨论】:

  • @R..&larsmans:是的,我的意思是终端(bash 是外壳)...我更正了。 @larsmans:2)我编辑了最初的帖子,放了一个简单的代码。
  • 谢谢。我已经知道了,我希望有另一种解决方案......所以,我将手动保存输入。关于第一个问题,我将根据终端窗口大小调整 ncurses 窗口的大小,或者我将使用转义序列来调整终端窗口的大小。
  • 这个答案有几个问题(见我的 cmets)。
【解决方案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 有一个预定义的信号处理程序,但在 application 级别,处理KEY_RESIZE 是推荐的方式。 ncurses-examples 中有几个程序可以做到这一点。
  2. 在窗口中向上 移动行必然会将一些移出 窗口。这意味着将行移到 窗口中以替换 那些离开的行。 “窗口”就是这样:一个有限大小的数据视图。对于不同尺寸的视图,建议开发者使用“pads”(见manual page)。滚动手册页中的注释提到了空白颜色(替换线)的一些问题。将替换项留空还是用应用程序的数据填充它们取决于应用程序。诅咒不会自动执行此操作(即使是垫子也不行)。

【讨论】:

    【解决方案3】:

    您不能从 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");
    }
    

    【讨论】:

      猜你喜欢
      • 2016-03-21
      • 2013-10-21
      • 2010-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-03
      • 1970-01-01
      • 2017-11-06
      相关资源
      最近更新 更多