原地址: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(); //将输出立刻显示出来 一般习惯来说是输出之后立刻refreshvoid 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:
- /*
- 写一个时间显示屏幕
- 初始化
- 循环显示时间 并刷新
- 释放资源
- */
- #include <curses.h>
- #include <time.h> //localtime
- #include <unistd.h> //sleep
- void init();
- void drawui();
- void bussiness();
- void destory();
- int main()
- {
- init();
- drawui();
- bussiness();
- destory();
- }
- void init()
- {
- initscr();
- }
- void destory()
- {
- endwin();
- }
- void drawui()
- {
- box(stdscr,0,0);
- }
- void bussiness()
- {
- time_t tt;
- struct tm* t;
- while(1)
- {
- tt = time(0);
- t = localtime(&tt);
- mvprintw(LINES/2,(COLS-8)/2,"%02d:%02d:%02d"
- ,t->tm_hour,t->tm_min,t->tm_sec);
- refresh(); //一定要记得刷新 不然不显示
- sleep(1);
- }
- }
/*
登录界面
1初始化
2绘制界面
头
绘制用户名输入区
绘制密码输入区
3等待输入
4结束
*/
- #include <unistd.h>
- #include <curses.h>
- #include <string.h>
- //#include <stdlib.h>
- void init();
- void drawLogin();
- void destory();
- int main()
- {
- init();
- drawLogin();
- destory();
- return 0;
- }
- void init()
- {
- initscr();
- }
- void drawLogin()
- {
- char *heads = "BSS BUSSINESS SUPPORT SYSTEM";
- char *user = "USER[ ]";
- char *pwd = "PWD [ ]";
- box(stdscr,0,0);
- attron(A_BOLD);
- mvaddstr(3,(COLS-strlen(heads))/2,heads);
- attroff(A_BOLD);
- mvhline(4,(COLS-strlen(heads))/2,0,strlen(heads));
- mvaddstr(8,(COLS-strlen(user))/2,user );
- mvaddstr(10,(COLS-strlen(pwd))/2,pwd);
- }
- void destory()
- {
- refresh();
- getch(); //按一个键推出
- endwin();
- }
4 输入
4.1 字符输入
int getch(void); 返回输入的字符 ,并在光标处回显,光标向前移动int wgetch(WINDOW *win);
int mvgetch(int y, int x); 返回输入的字符,并在指定的地方显示
int mvwgetch(WINDOW *win, int y, int x);
- #include <unistd.h>
- #include <curses.h>
- #include <string.h>
- //#include <stdlib.h>
- void init();
- void draw();
- void destory();
- int main()
- {
- init();
- draw();
- destory();
- return 0;
- }
- void init()
- {
- initscr();
- }
- void draw()
- {
- char ch;
- while(1)
- {
- ch=mvgetch(LINES/2,COLS/2);
- mvprintw(20,10,"your input is %c(%d)",ch,ch);
- refresh();
- }
- }
- void destory()
- {
- endwin();
- }
有些按键显示的结果不正确 在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);
//输出一个字符 并使字符随着方向键移动
- #include <curses.h>
- int main()
- {
- int ch,x=5,y=5;
- initscr();
- noecho();//防止回显
- keypad(stdscr,TRUE); //使功能键有效
- mvaddch(y,x,'S');
- while(1)
- {
- ch = getch();
- mvaddch(y,x,' ');
- switch(ch)
- {
- case KEY_UP :
- y--;
- break;
- case KEY_DOWN:
- y++;
- break;
- case KEY_LEFT:
- x--;
- break;
- case KEY_RIGHT:
- x++;
- break;
- }
- if(x<0 || y < 0)
- {
- clear();
- }
- mvaddch(y,x,'A');
- refresh();
- }
- endwin();
- return 0;
- }
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, ...);
int wscanw(WINDOW *win, char *fmt, ...);
int mvscanw(int y, int x, char *fmt, ...);
int mvwscanw(WINDOW *win, int y, int x, char *fmt, ...);
- #include <unistd.h>
- #include <curses.h>
- #include <string.h>
- //#include <stdlib.h>
- void init();
- void draw();
- void dealInput();
- void destory();
- int main()
- {
- init();
- draw();
- dealInput();
- destory();
- return 0;
- }
- void init()
- {
- initscr();
- }
- void draw()
- {
- mvaddstr(2,2,"[ ]+[ ]=[ ]");
- }
- void dealInput()
- {
- int a,b,ch;
- while(1)
- {
- mvaddstr(2,3," ");
- mvaddstr(2,11," ");
- mvaddstr(2,19," ");
- mvscanw(2,3,"%d",&a);
- mvscanw(2,11,"%d",&b);
- mvprintw(2,19,"%d",a+b);
- refresh();
- mvaddstr(3,3,"is continue? (y/n)");
- ch = getch();
- if(ch == 'n')
- {
- break;
- }
- }
- }
- void destory()
- {
- endwin();
- }
5 窗口
为了好看subwin(); //创建子窗体(坐标采用子窗体坐标) 不用
derwin(); //创建子窗体(坐标采用父窗体坐标)
WINDOW *derwin(WINDOW *orig, int nlines, int ncols,
int begin_y, int begin_x);
- #include <curses.h>
- int main()
- {
- initscr();
- WINDOW *w;
- box(stdscr,0,0);
- w=derwin(stdscr,10,20,2,2);
- box(w,0,0);
- refresh();
- getch();
- endwin();
- }