为了账号安全,请及时绑定邮箱和手机立即绑定

C指针原理(29)-Ncurses-文本终端的图形

标签:
C++


1、安装Ncurses

Ncurses是一个能提供功能键定义(快捷键),屏幕绘制以及基于文本终端的图形互动功能的动态库。

Ncurses是一个能提供基于文本终端窗口功能的动态库. Ncurses可以:

· 只要您喜欢,您可以使用整个屏幕

· 创建和管理一个窗口

· 使用8种不同的彩色

· 为您的程序提供鼠标支持

· 使用键盘上的功能键

Ubuntu下

mysea@mysea-desktop:~$ sudo apt-get install libncurses5-dbg libncurses5-dev

mysea@mysea-desktop:~/test$ gcc -lncurses -o cursestest cursestest.c

Freebsd下

cd /usr/ports/devel/ncurses-devel

make install clean

2、hello,world

#include <curses.h>

int main(void){

    initscr();//初始化

    box(stdscr,ACS_VLINE,ACS_HLINE);//画边框

    mvaddstr(15,2,"hello,world");//在15,2显示字符串

    refresh();//刷新屏幕

    getch();//等待按键

    endwin();//结束

    return 0;    

}

编译及运行

dp@dp:~/cursestest % gcc -lncurses 1.c -o mytest

dp@dp:~/cursestest % ./mytest

 3、色彩

然后编写下面代码:

#include <ncurses.h>

#include <locale.h>

#include <stdio.h>

int main(void){

//init_pair(short index,short foreground,short background)初始化颜色索引

//attron(COLOR_PAIR(索引号)|属性)

    setlocale(LC_ALL,"");

    initscr();//初始化

    box(stdscr,ACS_VLINE,ACS_HLINE);//画边框

    if (!has_colors()||start_color()==ERR){

        endwin();

        printf("终端不支持颜色\n");

        return 0;

    }

    init_pair(1,COLOR_GREEN,COLOR_BLACK);

    init_pair(2,COLOR_RED,COLOR_BLACK);

    init_pair(3,COLOR_WHITE,COLOR_BLUE);

    int i=0;

    for (i=1;i<=3;i++){

         attron(COLOR_PAIR(i));

         move(i,10);

         printw("hello,world:%d",i);

    }

    for (i=1;i<=3;i++){

         attron(COLOR_PAIR(i)|A_UNDERLINE);

         move(i+5,10);

         printw("hello,world:%d",i);

    }

    refresh();//刷新屏幕

    getch();//等待按键

    endwin();//结束

    

执行

4、对中文的支持

dp@dp:~/cursestest % cat 1.c

#include <ncurses.h>

#include <locale.h>

#include <stdio.h>

int main(void){

//init_pair(short index,short foreground,short background)初始化颜色索引

//attron(COLOR_PAIR(索引号)|属性)

    setlocale(LC_ALL,"");

    initscr();//初始化

    box(stdscr,ACS_VLINE,ACS_HLINE);//画边框

    if (!has_colors()||start_color()==ERR){

        endwin();

        printf("终端不支持颜色\n");

        return 0;

    }

    init_pair(1,COLOR_GREEN,COLOR_BLACK);

    init_pair(2,COLOR_RED,COLOR_BLACK);

    init_pair(3,COLOR_WHITE,COLOR_BLUE);

    int i=0;

    for (i=1;i<=3;i++){

         attron(COLOR_PAIR(i));

         move(i,10);

         printw("hello,世界%d",i);

    }

    for (i=1;i<=3;i++){

         attron(COLOR_PAIR(i)|A_UNDERLINE);

         move(i+5,10);

         printw("hello,世界:%d",i);

    }

    refresh();//刷新屏幕

    getch();//等待按键

    endwin();//结束

    return 0;    

}

编译时注意要使用ncursesw库,不使用ncurses库

dp@dp:~/cursestest % gcc -lncursesw 1.c -o mytest

dp@dp:~/cursestest % ./mytest

5、窗口与子窗口

dp@dp:~/cursestest % cat 1.c

#include <ncurses.h>

#include <locale.h>

int main(){

//init_pair(short index,short foreground,short background)初始化颜色索引

//attron(COLOR_PAIR(索引号)|属性)

//newwin建立窗口,derwin建立窗口的子窗口(相对于父窗口相对位置),subwin建立窗口的子窗口(相对于根窗口绝对位置)

    setlocale(LC_ALL,"");

    WINDOW *win1,*win2,*subwin;

    initscr();//初始化

    win1=newwin(15,50,1,1);//新窗口(行,列,begin_y,begin_x)

    box(win1,ACS_VLINE,ACS_HLINE);

    mvwprintw(win1,1,1,"WIN1");

    mvwprintw(win1,2,1,"您好,很高兴认识您");

    win2=newwin(10,40,10,30);//新窗口(行,列,begin_y,begin_x)

    box(win2,ACS_VLINE,ACS_HLINE);

    mvwprintw(win2,1,1,"WIN2");

    mvwprintw(win2,2,1,"您好,很高兴认识您");

    subwin=derwin(win2,3,20,3,5); //子窗口

    box(subwin,ACS_VLINE,ACS_HLINE);

    mvwprintw(subwin,1,5,"按任意键退出");//(窗口,y,x,字符串)

    refresh();//刷新整个大窗口stdscr

    wrefresh(win1);

    wrefresh(win2);

    touchwin(win1);//转换当前窗口为win1

    wrefresh(win1);

    getch();//win1显示完,等待按键显示win2

    touchwin(win2);//转换当前窗口为win2 

    //使用doupdate,可以事先定义要刷新的部分,然后刷新

    wnoutrefresh(win2);  

    wnoutrefresh(subwin);

    doupdate();

    getch();//等待按键

    delwin(win1);

    delwin(subwin);

    delwin(win2);

    endwin();//结束

    return 0;   

}

dp@dp:~/cursestest % gcc -lncursesw 1.c -o mytest

dp@dp:~/cursestest % ./mytest

6、自动滚屏

dp@dp:~/cursestest % cat 2.c

#include <ncurses.h> 

#include <locale.h> 

int main(void){ 

    int y,x,i,j,h,w;

    setlocale(LC_ALL,""); 

    WINDOW *pad; 

    initscr();//初始化 

    

    getmaxyx(stdscr,h,w);//获得屏幕尺寸 

    //画背景

    for(i=0;i<h;i++){

         for(j=0;j<w;j++){

             mvaddch(i,j,ACS_CKBOARD);

         }

    }

    refresh();

    

    //建立窗口

    pad=newpad(80,90);

    for (i=0;i<80;i++){

        char line[90];

        sprintf(line,"line %d\n",i);

        mvwprintw(pad,i,1,line);

    }

    refresh();

    prefresh(pad,0,1,5,10,20,25);//刷新pad。0,1  为基垫需要显示区域的左上角置(行列对,以下同此)。5,10,20,45为屏幕显示区域的左上角和右下角位置

  

    for(i=0;i<65;i++){

        prefresh(pad,i+1,1,5,10,20,25);//刷新pad,实现流屏;

        usleep(30000); 

    }

    getch();//等待按键

    delwin(pad); 

    endwin();//结束 

    return 0;    

}

dp@dp:~/cursestest % gcc -lncursesw 2.c -o mytest

dp@dp:~/cursestest % ./mytest

7、在窗口中移动光标

dp@dp:~/cursestest % cat 2.c

#include <ncurses.h> 

#include <locale.h> 

int main(void){ 

//init_pair(short index,short foreground,short background)初始化颜色索引 

//attron(COLOR_PAIR(索引号)|属性) 

//newwin建立窗口,derwin建立窗口的子窗口(相对于父窗口相对位置),subwin建立窗的子窗口(相对于根窗口绝对位置) 

    int x,y;

    setlocale(LC_ALL,""); 

    WINDOW *win1,*win2,*subwin; 

    initscr();//初始化 

    win1=newwin(15,50,1,1);//新窗口(行,列,begin_y,begin_x) 

    box(win1,ACS_VLINE,ACS_HLINE); 

    mvwprintw(win1,1,1,"WIN1"); 

    mvwprintw(win1,2,1,"myhaspl@myhaspl.com"); 

    win2=newwin(10,40,10,30);//新窗口(行,列,begin_y,begin_x) 

    box(win2,ACS_VLINE,ACS_HLINE); 

    wmove(win2,1,1);//移动某窗口的光标

    printw("WIN2");

    wmove(win2,2,1);//移动某窗口的光标。(窗口,y,x)

    printw("myhaspl@myhaspl.com"); 

    subwin=derwin(win2,3,20,4,5); //子窗口 

    box(subwin,ACS_VLINE,ACS_HLINE); 

    mvwprintw(subwin,1,5,"按任意键退出");//(窗口,y,x,字符串) 

       

    refresh();//刷新整个大窗口stdscr 

    wrefresh(win1); 

    wrefresh(win2); 

    

    move(5,60);//在stdscr移动光标

    printw("hello.........");

    touchwin(win1);//转换当前窗口为win1 

    wrefresh(win1); 

    getch();//win1显示完,等待按键显示win2 

    touchwin(win2);//转换当前窗口为win2  

    //使用doupdate,可以事先定义要刷新的部分,然后刷新 

    wnoutrefresh(win2);   

    wnoutrefresh(subwin); 

    doupdate(); 

    getyx(subwin,y,x);//获得当前逻辑光标位置

    mvwprintw(subwin,y+1,x,"................");//在“按任意键退出"下一行输出"..............."

    getch();//等待按键 

    delwin(win1); 

    delwin(subwin); 

    delwin(win2); 

    endwin();//结束 

    return 0;    

编译后运行

dp@dp:~/cursestest % gcc -lncursesw 2.c -o mytest

dp@dp:~/cursestest % ./mytest

8、菜单

dp@dp:~/cursestest % cat 2.c

#include <locale.h>

#include <menu.h> 

#include <stdio.h>

#include <ctype.h>

//定义菜单项

static const char *menus[]={

   "1-1","1-2","1-3","2-1","2-2","2-3"

};

#define CITEM sizeof(menus)/sizeof(menus[0])//菜单项数

ITEM *items[CITEM];

int main(int argc,char *argv[]){

    int i;

    int ch;

    int mrows,mcols;

    WINDOW *win,*subwin;

    MENU *mymenu;

    

    //初始化屏幕

    initscr();

    //不用等待回车键

    cbreak();

    //不回显

    noecho();

    //可以处理功能键 

    keypad(stdscr,TRUE); 

    

    //建立菜单项

    for(i=0;i<CITEM;i++){

        items[i]=new_item(menus[i],menus[i]);//第二个参数为菜单项的描述

    }  

    //建立菜单

    mymenu=new_menu(items);

    set_menu_format(mymenu,CITEM,1);    //设置CITEM行1列的菜单

    set_menu_mark(mymenu,">");//菜单选中的MARK

    //获得菜单的行列数

    scale_menu(mymenu,&mrows,&mcols);

    //建立窗口和子窗口

    win=newwin(mrows+2,mcols+2,3,30);

    keypad(win,TRUE);

    box(win,0,0);

    subwin=derwin(win,0,0,1,1);

    //设置菜单的窗口

    set_menu_sub(mymenu,subwin);    

    //在子窗口上放置菜单

    post_menu(mymenu);

    

    refresh();

    wrefresh(win);

    //获得输入,并移动选择到相应的菜单项 

    while(toupper(ch=wgetch(win))!='\n'){

          if(ch==KEY_DOWN)

             menu_driver(mymenu,REQ_DOWN_ITEM);//移动菜单选择

          else if(ch==KEY_RIGHT)

             menu_driver(mymenu,REQ_RIGHT_ITEM);

          else if (ch==KEY_UP)

             menu_driver(mymenu,REQ_UP_ITEM); 

          else if (ch==KEY_LEFT)

             menu_driver(mymenu,REQ_LEFT_ITEM);

    }

    //输出当前项

    mvprintw(LINES-2,0,"you select the item :%s\n",item_name(current_item(mymenu)));

    refresh();

    unpost_menu(mymenu);

    getch();

    //释放内存

    free_menu(mymenu);

    for(i=0;i<CITEM;i++) free_item(items[i]);

    endwin();

    return 1;

}

编译并运行

dp@dp:~/cursestest % gcc -lncursesw -lmenu 2.c -o mytest

dp@dp:~/cursestest % ./mytest

©著作权归作者所有:来自51CTO博客作者myhaspl的原创作品,如需转载,请注明出处,否则将追究法律责任


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消