5-linux学习笔记之-----curses

curses

-------------------------------------------------------------

   Curses:CUI

       UI: User Interface.

       GUI:  字符界面

        CUI:  图形界面

  使用一套封装库   libcurse.so

     /ust/lib 目录下

  编译程序的时候需要指定  -lcurses

       老版本: libcurses.so

  新版本:   libncurses.so

--------------------------------------------------------------------------------

        printf/scanf  是标准IO

  大部分标准IO可以重定向到终端。/dev/tty   或者  /dev/pts/1


      curses不是标准输出,是终端输出,无法重定向。

  注意: 为了防止printf重定向到终端破坏UI,建议不要在curses中使用标志IO

 1. 编程模型

   初始化终端 initscr

           操作终端(输入/ 输出/ 定位/刷新……)

   释放终端 endwin

    2.显示

   2.1 图形输出

     border-------------在指定窗口输出一个边界

     box-----------------在指定窗体输出一个边界

     hline----------------水平线

     vline-----------------垂直线

     属性字符: 字节= 属性字节+ 字符字节。

     注意:

        box 需要窗体

        initscr 返回被初始化的窗体:标准屏幕

       实际上curses 定义了一个全局stdscr就是标准屏幕。

       

       curses 库函数命名规则:

       ××××××    标准屏幕stdscr进行操作

       w××××    指定窗体

       mv×××    指定位置

       mvw×××   指定窗体的指定位置

   2.2 刷屏

      void   refresh();   只刷标准屏幕

      void wreesh(WINDOW*); 刷指定窗体的屏幕

      原则: 从里到外刷

   2.3 字符输出

       addchar();

                        属性字符:一个字符加上属性('  '  |  属性 )(比如让字符加粗,加上下划线)

       如: mvaddch(2,10,'A' | A_BOLD);

            常见属性的宏定义如下:

             Name            Description
              ────────────────────────────────────────────────────────────
              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_ITALIC        Italics (non-X/Open extension)
              A_CHARTEXT      Bit-mask to extract a character
              COLOR_PAIR(n)   Color-pair number n

          ______________________________________________________________________________
   

   2.4 字符串的输出

      int  addstr(const char *);

           2.5 格式字符串的输出

       printw(const    char*,..............);

        3. 字符属性与颜色

   3.1 判断终端释放支持颜色

       bool   has_colors();  (可以不用判定,现在大多数系统都支持颜色的)

   3.2 初始化颜色

       int  start_color();

           3.3 定义颜色对

       int   init_pair(short  pair,short  fore, shot );

   3.4 使用颜色对(对颜色属性的访问)

       COLOR_PAIR(shot  pair);

   3.5 设置属性

       attron();  开启属性

       attroff();  关闭属性

      注意:这组函数一定要在调用了initscr之后使用

字符的颜色属性有8种

——————————————————————————

             COLOR_BLACK
             COLOR_RED
             COLOR_GREEN
             COLOR_YELLOW
             COLOR_BLUE
             COLOR_MAGENTA
             COLOR_CYAN
             COLOR_WHITE


——————————————————————————

文档的查看:

_______________________

$  man   attron 

$ man  addch

$ man box

$ man attron

_____________________________


这是curses的一个最简单的例子


/// cur_init.c
#include 

int main()
{
	WINDOW *w = initscr(); // 初始化终端
	mvhline(2,10,'-',20);
	mvvline(2,10,'|',20);
	refresh();	
	getch(); /// 等待一个字符的输入
	endwin(); /// 释放终端
	return 0;
}


——————————————————————————————
makefile
cur_init:
    gcc cur_init.c   -omain  -lcurses(记得加上库)
 
———————————————————————————————


字符属性与颜色的例子


/// cur_out.c
#include 

int main()
{
	initscr();
	if(has_colors() == TRUE)  /// 判断是否支持颜色
	{
		start_color(); /// 初始化颜色的显示功能
		/// 颜色只能是库里面的8种颜色的组合
		init_pair(1,COLOR_RED,COLOR_WHITE);
		init_pair(2,COLOR_BLUE,COLOR_GREEN);
		init_pair(3,COLOR_BLACK,COLOR_WHITE);
		
		bkgd(COLOR_PAIR(3));/// 调用第3个颜色对
	}
	box(stdscr,0,0);
	// 对颜色的访问是通过COLOR_PAIR 函数的调用完成的
	mvaddch(2,10,ACS_PI | COLOR_PAIR(1));
	mvaddch(2,11,ACS_PI | COLOR_PAIR(2));
	
	// 开启字符属性
	attron(COLOR_PAIR(1));
	// 字符串输出
	mvaddstr(5,10,"Hello   我的女神");
	/// 关闭字符属性
	attroff(COLOR_PAIR(1));
	
	attron(COLOR_PAIR(2) |  A_UNDERLINE);
	mvaddstr(7,10,"Hello  Fellow!");
	attroff(COLOR_PAIR(2) | A_UNDERLINE);
	
	/// 格式字符串输出
	mvprintw(9,10,"行:%d,列:%d",LINES,COLS);// 打印行和列
	getch();
	endwin();
	return 0;
}


截图如下,显示的非常简单

5-linux学习笔记之-----curses_第1张图片


××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××

对乱码问题的解决方案:(编码解决)
1. 在vi设置编码 :
        $:set      encoding = 编码 (  gb2312   ios-8859-1   utf-8)
2. ( man gcc)  
在编译器指定输出源文件编码  (  -finput-charset=gb2312)
      执行文件编码(-fexec-charset=charset)
  ---------------------------------------------------------
  $ gcc addstr.c  -omain -lcurses -finput-charset=gb2312
  ------------------------------------------------------------------
3. 终端指定编码:(鼠标直接设置编码)
 
4. 系统默认编码
    /etc/sysconfig /il8n 配置编码

总结: 我的结论是我使用UTF-8 始终都是乱码只有把 编辑器 和 终端 都设置成GB2312, 乱码问题可以解决,

首先说明一点我使用的系统是  ubuntu  32位 14.04 

×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××

案例:

   1. 时间显示屏幕

      1. 初始化

      2. 循环显示时间,并且睡眠


/// demo2.c 

#include 
#include 
#include 

void init();
void drawui();
void busines();
void destroy();

main()
{
	init();
	drawui();
	busines();
	destroy();
}

void init()
{
	initscr();
	if(has_colors() == TRUE)
	{
		start_color();
		init_pair(1,COLOR_RED,COLOR_WHITE);
		init_pair(2,COLOR_BLACK,COLOR_GREEN);
		bkgd(COLOR_PAIR(2));
	}
}
void drawui()
{
	box(stdscr,0,0);
}
void busines()
{
	time_t tt;
	struct tm *t;
	while(1)
	{
		//取取时间
		tt = time(0);
		// 把时间转换为struct tm 结构体
		t = localtime(&tt);
		// 显示时间
		attron(COLOR_PAIR(1));
		mvprintw(LINES/2,(COLS-8)/2,"%02d:%02d:%02d",
		t->tm_hour,t->tm_min,t->tm_sec);
		attroff(COLOR_PAIR(1));
		// 刷新屏幕
		refresh();
		sleep(1);
		
		
	}
}
void destroy()
{
	endwin();
}


5-linux学习笔记之-----curses_第2张图片


  2. 做一个登陆界面

        1. 初始化

        2. 绘制界面

        3.等待输入

        4.结束   


#include 
#include 
#include 
#include 

void init();
void drawLogin();
void destroy();

main()
{
	init();
	drawLogin();
	destroy();
}

void init()
{
   initscr();
   if(has_colors() == TRUE)
   {
   		start_color();
   		init_pair(1,COLOR_BLUE,COLOR_WHITE);
   		init_pair(2,COLOR_RED,COLOR_GREEN);
   		bkgd(COLOR_PAIR(1));
   }
}

void drawLogin()
{
	char  *heads = "图书馆图书管理系统";
	char *user = "用户[        ]";
	char *pass = "密码[        ]";
	
	box(stdscr,0,0);
	attron(A_BOLD | COLOR_PAIR(2)); // 打开字符属性
	mvaddstr(3,(COLS-strlen(heads)) /2,heads);
	attroff(A_BOLD| COLOR_PAIR(2));
	mvaddstr(6,(COLS-strlen(user))/2,user);
	mvaddstr(8,(COLS-strlen(pass))/2,pass);
	refresh();
}
void destroy()
{
	refresh();
	getch();
	endwin();
}

5-linux学习笔记之-----curses_第3张图片


  4.键盘输入

     1. 字符输入

        int   getch(); // 返回字符

       int   getstr(char  *string) ; //对其返回字符串长度没有限制,很容易出现问题

       int   getnstr(char *string , int number_of_character); 对读取的字符数目加以限制

 举例:

/// getch.c
#include 

main()
{
	int ch;
	// 初始化
	initscr();
	noecho(); /// 隐藏光标
	// 循环输入
	while(1)
	{
		ch = mvgetch(5,10);
		// 循环显示输入
		mvprintw(8,10,"你输入的是:%c(%d)",ch,ch);
	}
	// 释放
	endwin();
}

案例:

    使用键盘控制字母在屏幕上移动。

    补充:

       (1)noecho(); 禁止回显(输入的信息不能显示在屏幕上)

       (2)curses  清除屏幕:man  3 clear

                                        int   clear (void);

                                        int  erase(void);

       (3)光标控制:

           得到光标位置: getsyx

           设置光标位置: setsyx();

                                        设置光标是否可见:int   curs_set(int  visibility); (0 不可见 1可见)

       (4)keypad 模式

        curses 在启动时会关闭转义序列与逻辑键之间的转换功能,该功能需要通过调用keypad函数来启用


/// demo4.c

#include 

main()
{
	int ch;
	int x = 5,y = 5;
	initscr();
	noecho(); // 禁止回显
	keypad(stdscr,TRUE); // 功能键的开启,这个必须要
	mvaddch(y,x,'A'); /// 移动的是字符A
	while(1)
	{
		ch = getch();
		mvaddch(y,x,' '); // 使用空格清屏
		//clrtoeol();
		//clear(); // 删除整个屏幕
		//erase();
		switch(ch)
		{
			case KEY_UP:
				y--;
				break;
			case KEY_DOWN:
			    y++;
				break;
			case KEY_LEFT:
				x--;
				break;
			case KEY_RIGHT:
				x++;
				break;
		}
		/// 在指定位置输出
		mvaddch(y,x,'A');
		refresh();
	}
}

最后一个小例子

#include 

void init();
void drawUi();
void dealInput();
void destroy();

main()
{
	init();
	drawUi();
	dealInput();
	destroy();  
}

void init()
{
    initscr();
}
void drawUi()
{
    mvaddstr(2,2,"[    ] + [    ] = [      ]");
    refresh();
}
void dealInput()
{
    int a , b;
    int c ;
    while(1)
    {
       mvscanw(2,4,"%d",&a);
       mvscanw(2,12,"%d",&b);
       mvprintw(2,23,"%d",a+b);
       refresh();
    }
}
void destroy()
{
   endwin();
}



 5. 窗体

    subwin(); // 创建子窗体(坐标采用标准屏幕坐标)

    derwin(); // 创建子窗体(坐标采用父窗体坐标)


总结: curses 的编程模式比较固定,用的是一套库,都是函数的调用,使用并不是很难,


      



 

                 

你可能感兴趣的:(Linux学习,curses,linux,C)