linux编程学习笔记(十一) curses CUI界面

原地址:http://blog.csdn.net/a8887396/article/details/9077533


CUI 字符界面

GUI:图形界面


使用一套封装库 libcruses.so
老版本 libcurses.so
新版本 libncruses.so
编译时需要-lcurses 或者-lncurses
如果头文件curses.h不存在 则尝试使用ncurses.h


printf /scanf标准IO
大部分标准IO重定向到 /dev/tty /det/pts/1


curses就是终端输出


为了防止printf重定向到终端破坏UI,禁止用printf输出


1 编程模型

初始化终端 WINDOW* initscr();
返回一个被初始化的窗体 
操作终端(输入/输出/定位/刷新)
释放终端 int endwin()

2 显示

2.1 图形输出

border  打印一个边框
int border(chtype ls, chtype rs, chtype ts, chtype bs, 
chtype tl, chtype tr, chtype bl, chtype br);
8个参数分别为  左 右 上 下 左上 右上 左下 右下 的字符
可以采用8个0来采用默认边框
border('a','b','c','e','f','g','h','g');
border(0,0,0,0,0,0,0,0);
wborder 在指定窗体画一个边框


box  打印一个边框
int box(WINDOW *win, chtype verch, chtype horch);
box需要窗体,只能设置水平和垂直的边框字符
标准屏幕除了在init_scr()的返回外 还可以使用全局变量stdscr
box(stdscr,0,0); 效果和border(0,0,0,0,0,0,0,0);是一样的

hline  画水平线
hline         在 标准窗体 光标位置 画水平线
whline      在 指定窗体 光标位置 画水平线
mvhline    在 标准窗体 指定位置 画水平线
mvwhline 在 指定窗体 指针位置 画水平线


vline 画垂直线(同hline)


属性字符:字节=属性字节+字符字节
注意:
box需要窗体
initscr返回被初始化的窗体:标准屏幕
curses定义了一个全局变量stdscr表示标准窗体
命名规则:
***  某函数
w*** 在某窗体运行某函数
mv*** 在指定位置运行某函数
mvw***  在指定窗体指定位置运行某函数


2.2刷屏

void  refresh(); //将输出立刻显示出来 一般习惯来说是输出之后立刻refresh
void  wrefresh(WINDOW*);
从里到外刷屏





3 字符输出

       int addch(const chtype ch);
       int waddch(WINDOW *win, const chtype ch);
       int mvaddch(int y, int x, const chtype ch);
       int mvwaddch(WINDOW *win, int y, int x, const chtype ch);
属性字符: ' '|属性   (字符  位预算符 属性)


属性(man attron中的)
      A_NORMAL        Normal display (no highlight)
               A_STANDOUT      Best highlighting mode of the terminal.
               A_UNDERLINE     Underlining
               A_REVERSE       Reverse video
               A_BLINK         Blinking
               A_DIM           Half bright
               A_BOLD          Extra bright or bold
               A_PROTECT       Protected mode
               A_INVIS         Invisible or blank mode
               A_ALTCHARSET    Alternate character set
               A_CHARTEXT      Bit-mask to extract a character
               COLOR_PAIR(n)   Color-pair number n


特殊字符
man  addch中还可以找到不知到如何打印的字符 譬如PI
ACS_PI         *         greek pi
       ACS_PLMINUS    #         plus/minus
       ACS_PLUS       +         plus
       ACS_RARROW     >         arrow pointing right
       ACS_RTEE       +         right tee
       ACS_S1         -         scan line 1
等等







3 字符属性与颜色

颜色属性

3.1 判定终端是否支持颜色(现在的终端一般都支持,可以不做判定)

bool has_colors(void); 

3.2 初始化颜色

int start_color(void);

3.3 定义颜色对

int init_pair(short pair, short f, short b);
编号 前景色 背景色
最多支持8对颜色 1-8
颜色可选的有:
COLOR_BLACK
COLOR_RED
COLOR_GREEN
COLOR_YELLOW
COLOR_BLUE
COLOR_MAGENTA 紫色
COLOR_CYAN 青色
COLOR_WHITE


if(has_colors() == TRUE)
{
start_color(); //初始化颜色
init_pair(1,COLOR_RED,COLOR_YELLOW);
init_pair(2,COLOR_BLUE,COLOR_WHITE);
init_pair(3,COLOR_BLACK,COLOR_WHITE);
bkgd(COLOR_PAIR(3));
}




3.4 使用颜色对(宏)

COLOR_PAIR(short pair) 
设置字符颜色 在字符的属性中设置
mvaddch(2,10,'A'|A_UNDERLINE|COLOR_PAIR(1));
设置背景颜色 bkgd 函数
init_pair(3,COLOR_BLACK,COLOR_WHITE);
bkgd(COLOR_PAIR(3)); //设置背景色



这组函数一定要在init_scr之后使用

#include <curses.h>
int main()
{
initscr();//初始化窗体
if(has_colors() == TRUE)
{
start_color(); //初始化颜色
init_pair(1,COLOR_RED,COLOR_YELLOW); //定义颜色对
init_pair(2,COLOR_BLUE,COLOR_CYAN);
init_pair(3,COLOR_BLACK,COLOR_WHITE);
bkgd(COLOR_PAIR(3)); //设置背景色
}
box(stdscr,0,0);//输出边框
mvaddch(2,10,'A'|A_UNDERLINE|COLOR_PAIR(1)); //输出字符
mvaddch(10,20,'B'|A_BOLD|COLOR_PAIR(1));
mvaddch(10,21,ACS_PI|COLOR_PAIR(2));//输出特殊字符

getch();
endwin();//释放窗体
}



3.5 输出字符串addstr

       int addstr(const char *str);输出字符串
       int addnstr(const char *str, int n); 输出字符串的前n个字符
       int waddstr(WINDOW *win, const char *str);
       int waddnstr(WINDOW *win, const char *str, int n);
       int mvaddstr(int y, int x, const char *str);
       int mvaddnstr(int y, int x, const char *str, int n);
       int mvwaddstr(WINDOW *win, int y, int x, const char *str);
       int mvwaddnstr(WINDOW *win, int y, int x, const char *str, int n);

mvaddstr(1,10,"hello world");//输出字符串


3.6格式字符串输出printw

int printw(const char *fmt, ...);
       int wprintw(WINDOW *win, const char *fmt, ...);
       int mvprintw(int y, int x, const char *fmt, ...);
       int mvwprintw(WINDOW *win, int y, int x, const char *fmt, ...);





3.7 设置属性

attron() 开启属性
attroff() 关闭属性

attron(COLOR_PAIR(1)); //开启属性
mvaddstr(1,10,"hello world");//输出字符串
attroff(COLOR_PAIR(1));//关闭属性


attron(COLOR_PAIR(2)| A_UNDERLINE); //开启2个属性
mvaddnstr(3,10,"hahahahaha",3); //控制输出字符串的前几个字符 此处前3
attroff(COLOR_PAIR(2)|  A_UNDERLINE);//关闭2个属性


案例1:

[cpp]  view plain copy
  1. /* 
  2. 写一个时间显示屏幕 
  3.     初始化 
  4.     循环显示时间 并刷新 
  5.     释放资源 
  6. */  
  7.   
  8. #include <curses.h>  
  9. #include <time.h> //localtime  
  10. #include <unistd.h> //sleep  
  11.   
  12. void init();  
  13. void drawui();  
  14. void bussiness();  
  15. void destory();  
  16.   
  17. int main()  
  18. {  
  19.     init();  
  20.     drawui();  
  21.     bussiness();      
  22.     destory();  
  23. }  
  24.   
  25.   
  26. void init()  
  27. {  
  28.     initscr();  
  29. }  
  30. void destory()  
  31. {  
  32.     endwin();  
  33. }  
  34.   
  35. void drawui()  
  36. {  
  37.     box(stdscr,0,0);  
  38. }  
  39.   
  40. void bussiness()  
  41. {  
  42.     time_t tt;  
  43.     struct tm* t;  
  44.     while(1)  
  45.     {  
  46.         tt = time(0);  
  47.         t = localtime(&tt);  
  48.         mvprintw(LINES/2,(COLS-8)/2,"%02d:%02d:%02d"  
  49.             ,t->tm_hour,t->tm_min,t->tm_sec);    
  50.         refresh(); //一定要记得刷新 不然不显示  
  51.         sleep(1);  
  52.     }  
  53.       
  54.       
  55. }  



案例2:
/*
登录界面
1初始化
2绘制界面

绘制用户名输入区
绘制密码输入区
3等待输入
4结束
*/
[cpp]  view plain copy
  1. #include <unistd.h>  
  2. #include <curses.h>  
  3. #include <string.h>  
  4. //#include <stdlib.h>  
  5.   
  6. void init();  
  7. void drawLogin();  
  8. void destory();  
  9.   
  10. int main()  
  11. {  
  12.     init();  
  13.     drawLogin();  
  14.     destory();  
  15.       
  16.     return 0;  
  17. }  
  18.   
  19. void init()  
  20. {     
  21.     initscr();  
  22. }  
  23.   
  24. void drawLogin()      
  25. {  
  26.     char *heads = "BSS BUSSINESS SUPPORT SYSTEM";  
  27.     char *user =  "USER[                        ]";  
  28.     char *pwd  = "PWD [                        ]";  
  29.     box(stdscr,0,0);  
  30.     attron(A_BOLD);  
  31.     mvaddstr(3,(COLS-strlen(heads))/2,heads);  
  32.     attroff(A_BOLD);  
  33.     mvhline(4,(COLS-strlen(heads))/2,0,strlen(heads));  
  34.     mvaddstr(8,(COLS-strlen(user))/2,user );  
  35.     mvaddstr(10,(COLS-strlen(pwd))/2,pwd);  
  36.       
  37. }  
  38.   
  39. void destory()  
  40. {  
  41.     refresh();  
  42.     getch(); //按一个键推出   
  43.     endwin();  
  44. }  








4 输入

4.1 字符输入

int getch(void);       返回输入的字符 ,并在光标处回显,光标向前移动
       int wgetch(WINDOW *win);
       int mvgetch(int y, int x); 返回输入的字符,并在指定的地方显示

       int mvwgetch(WINDOW *win, int y, int x);

[cpp]  view plain copy
  1. #include <unistd.h>  
  2. #include <curses.h>  
  3. #include <string.h>  
  4. //#include <stdlib.h>  
  5.   
  6. void init();  
  7. void draw();  
  8. void destory();  
  9.   
  10. int main()  
  11. {  
  12.     init();  
  13.     draw();  
  14.     destory();  
  15.       
  16.     return 0;  
  17. }  
  18.   
  19. void init()  
  20. {     
  21.     initscr();  
  22. }  
  23.   
  24. void draw()   
  25. {  
  26.     char ch;  
  27.     while(1)  
  28.     {  
  29.         ch=mvgetch(LINES/2,COLS/2);  
  30.         mvprintw(20,10,"your input is %c(%d)",ch,ch);  
  31.         refresh();  
  32.     }  
  33.       
  34. }  
  35.   
  36. void destory()  
  37. {   
  38.     endwin();  
  39. }  



有些按键显示的结果不正确 在man getch中有 
 KEY_BREAK       Break key
                  KEY_DOWN        The four arrow keys ...
                  KEY_UP
                  KEY_LEFT
                  KEY_RIGHT
                  KEY_HOME        Home key (upward+left arrow)
                  KEY_BACKSPACE   Backspace
                  KEY_F0          Function keys; space for 64 keys
                                  is reserved.


4.2 控制函数 

禁止回显noecho (默认有回显) 
int noecho(void);


使功能键有效 (默认禁用功能键)
int keypad(WINDOW *win, bool bf);


//输出一个字符  并使字符随着方向键移动
[cpp]  view plain copy
  1. #include <curses.h>  
  2. int main()  
  3. {  
  4.     int ch,x=5,y=5;  
  5.     initscr();  
  6.       
  7.     noecho();//防止回显  
  8.     keypad(stdscr,TRUE); //使功能键有效   
  9.     mvaddch(y,x,'S');  
  10.       
  11.     while(1)  
  12.     {  
  13.         ch = getch();  
  14.         mvaddch(y,x,' ');  
  15.         switch(ch)  
  16.         {  
  17.             case KEY_UP :  
  18.                 y--;  
  19.             break;  
  20.             case KEY_DOWN:  
  21.                 y++;  
  22.             break;  
  23.             case KEY_LEFT:  
  24.                 x--;  
  25.             break;  
  26.             case KEY_RIGHT:  
  27.                 x++;  
  28.             break;  
  29.         }  
  30.   
  31.             if(x<0 || y < 0)  
  32.             {  
  33.                 clear();  
  34.             }  
  35.             mvaddch(y,x,'A');  
  36.             refresh();  
  37.     }  
  38.     endwin();  
  39.     return 0;  
  40. }  



4.3 清屏

int erase(void); //删除整个屏幕
       int werase(WINDOW *win);
       int clear(void); //删除整个屏幕
       int wclear(WINDOW *win);
       int clrtobot(void);//删除到屏幕结束
       int wclrtobot(WINDOW *win);
       int clrtoeol(void); //删到行尾
       int wclrtoeol(WINDOW *win)


4.4  光标控制

1得到光标位置 (这是一个宏)
void getsyx(int y, int x); 
        设置参数位置 
void setsyx(int y, int x);
设置光标是否可见
int curs_set(int visibility); 0不可见




4.5输入字符串

int getstr(char *str);
       int getnstr(char *str, int n);
       int wgetstr(WINDOW *win, char *str);
       int wgetnstr(WINDOW *win, char *str, int n);
       int mvgetstr(int y, int x, char *str);
       int mvwgetstr(WINDOW *win, int y, int x, char *str);
       int mvgetnstr(int y, int x, char *str, int n);

4.6格式化输入字符串

int scanw(char *fmt, ...);
       int wscanw(WINDOW *win, char *fmt, ...);
       int mvscanw(int y, int x, char *fmt, ...);
       int mvwscanw(WINDOW *win, int y, int x, char *fmt, ...);
[cpp]  view plain copy
  1. #include <unistd.h>  
  2. #include <curses.h>  
  3. #include <string.h>  
  4. //#include <stdlib.h>  
  5.   
  6. void init();  
  7. void draw();  
  8. void dealInput();  
  9. void destory();  
  10.   
  11. int main()  
  12. {  
  13.     init();  
  14.     draw();  
  15.     dealInput();  
  16.       
  17.     destory();  
  18.       
  19.     return 0;  
  20. }  
  21.   
  22. void init()  
  23. {     
  24.     initscr();  
  25. }  
  26.   
  27. void draw()   
  28. {  
  29.     mvaddstr(2,2,"[     ]+[     ]=[      ]");  
  30. }  
  31.   
  32. void dealInput()  
  33. {  
  34.     int a,b,ch;  
  35.     while(1)  
  36.     {  
  37.         mvaddstr(2,3,"     ");  
  38.         mvaddstr(2,11,"     ");  
  39.         mvaddstr(2,19,"     ");  
  40.         mvscanw(2,3,"%d",&a);  
  41.         mvscanw(2,11,"%d",&b);  
  42.         mvprintw(2,19,"%d",a+b);  
  43.         refresh();  
  44.         mvaddstr(3,3,"is continue? (y/n)");  
  45.         ch = getch();  
  46.         if(ch == 'n')  
  47.         {  
  48.             break;  
  49.         }  
  50.     }  
  51. }  
  52.   
  53. void destory()  
  54. {   
  55.     endwin();  
  56. }  
  57.       





5 窗口 

为了好看 
subwin(); //创建子窗体(坐标采用子窗体坐标) 不用
derwin(); //创建子窗体(坐标采用父窗体坐标)

  WINDOW *derwin(WINDOW *orig, int nlines, int ncols,
           int begin_y, int begin_x);
[cpp]  view plain copy
  1. #include <curses.h>  
  2.   
  3. int main()  
  4. {  
  5.     initscr();  
  6.     WINDOW *w;  
  7.     box(stdscr,0,0);  
  8.     w=derwin(stdscr,10,20,2,2);  
  9.     box(w,0,0);  
  10.       
  11.     refresh();  
  12.     getch();  
  13.     endwin();  
  14.       
  15. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值