必威体育Betway必威体育官网
当前位置:首页 > IT技术

图像化界面---CURSES(1)

时间:2019-10-09 03:42:08来源:IT技术作者:seo实验室小编阅读:67次「手机版」
 

curses

文章目录

  • 初始化
    • initscr() 函数
    • refresh() 函数
    • endwin() 函数
    • raw() 函数和 和 cbreak() 函数
    • echo() 函数和 和 noecho() 函数
    • keypad() 函数
    • halfdelay() 函数
  • 输出函数
  • 输入函数
  • 输出修饰

初始化

initscr() 函数

**initscr()函数将终端屏幕初始化为curses 模式。**它用来清除屏幕上所有的字符,并等待下一部处理。所以在调用其它的curses 函数前,要先调用 initscr()函数初始化屏幕。这个函数初始化了 curses 系统并且为当前屏幕(也就是“stdscr”)和相关的数据结构分配内存。在以前的计算机上曾经出现过一个极端的例子:因为系统中的可用内存太小,以至于initscr()函数无法分配足够的内存给相关的数据结构,从而导致curses 系统初始化失败。

refresh() 函数

printw()函数用于把字符串输出到虚拟的屏幕上。这个函数在用法上和printf()函数很像。不同的是:printw()函数把字符串输出到“stdscr”的虚拟窗口坐标(0,0)上(从显示的结果来看,坐标(0,0)在屏幕的左上角上)。现在该说说这个神秘的refresh()函数了。**在我们使用printw 函数打印时,实际上这个消息打印到了一个叫作“stdscr”的虚拟窗口上,没有被直接输出到屏幕上。printw()函数的作用是不断将一些显示标记和相关的数据结构写在虚拟显示器上,并将这些数据写入stdscr 的缓冲区内。为了显示这些缓冲区中的数据我们必须使用refresh()函数告诉 curses系统将缓冲区的内容输出到屏幕上。**通过这种机制程序员能够不断在虚拟屏幕上写数据。然后调用 refresh()函数让输出的操作看起来是一次完成的。因为 refresh()函数只核查窗口和数据中变动的部分,这种富有弹性的设计提供了一个高效的反馈机制。但是这有时很打击初学者的积极性。因为对于初学者来说忘记在输出后调用refresh()函数是很恼人的错误。不过不用担心,很多人都会犯这样的错误。

endwin() 函数

最后,别忘了退出 curses 模式。否则,在程序结束后你的终端可能会运转得不正常。**endwin()函数释放了 curses 子系统和相关数据结构占用的内存,使你能够正常返回控制台模式。**这个函数必须是在你完成所有的 curses 操作以后才可以调用。

#include<ncurses.h>
int main()
{
	initscr();      //初始化,进入ncurses模式
	printw("Hello  World  !!!");  //在虚拟屏幕上打印hello world!!!
	refresh();     //将虚拟屏幕上的内容写到显示器上,并刷新
	getchar();     //等待用户输入
	endwin();      //退出ncurses模式
	return 0;
}

raw() 函数和 和 cbreak() 函数

通常情况下,终端驱动程序会缓冲用户输入的字符,直到遇到换行符或回车符后,这些字符才可以被使用。但是大多数程序要求字符在输入时就可以被使用。raw()和 cbreak()两个函数都可以禁止行缓冲(line buffering)。区别是:在 raw()函数模式下,处理挂起(CTRL­Z)、中断或退出(CTRL­C)等控制字符时,将直接传送给程序去处理而不产生终端信号;而在cbreak()模式下,控制字符将被终端驱动程序解释成其它字符。就我个人而言,比较喜欢使用 raw()函数,因为用它可以做一些一般用户无法进行的控制操作。

echo() 函数和 和 noecho() 函数

这两个函数用来控制是否将从键盘输入的字符显示在终端上。调用 noecho()函数禁止输入的字符出现在屏幕上。也许程序员希望用户在进行控制操作时,需要屏蔽掉控制字符(如组合键操作),或调用 getch()函数读取键盘字符时,不想显示输入的字符(如在控制台输入登陆密码)。大多数的交互式应用程序在初始化时会调用noecho()函数,用于在进行控制操作时不显示输入的控制字符。这两个函数给予程序员很大的灵活性,使程序员可以在窗口中的任意地方,实现输入字符的显示和屏蔽,而不需要刷新屏幕。

keypad() 函数

这个函数允许使用功能键,例如:F1、F2、方向键等功能键。几乎所有的交互式程序都需

要使用功能键,因为绝大多数用户界面主要用方向键进行操作。使用keypad(stdscr,TURE)

就为“标准屏幕”(stdscr)激活了功能键。

halfdelay() 函数

halfdelay()函数会启用半延时模式(half­delay mode)。和 cbreak()函数一样,当程序需要用户输入字符时,输入的每个字符都是可用的。给halfdelay()传递一个整型参数(以 0.1 秒为单位),它就会在这个参数时间内等待输入。如果没有有效的输入,则返回ERR。

一般来说,这个函数在需要等待输入的程序中会用到。如果用户没有在规定时间内给出有效

输入,程序就可以去处理其它事情。最常见例子就是在输入密码时做出超时响应

输出函数

在 curses 函数中有三类输出函数,它们分别是:

  1. addch() 系列:将单一的字符打印到屏幕上,可以附加加字符修饰参数的一类函数。
  2. printw() 系列:和 printf()一样的具有格式化输出的一类函数。
  3. addstr() 系列:打印字符串的一类函数。

addch() 系列函数

addch()函数用于在当前光标位置输入单个字符,并将光标右移一位。你可以使用这个函数

输出一个字符,并给其添加修饰。

给单个字符关联属性有两种方法:

使用修饰宏(通过“或”运算符)修饰。这些修饰宏可以在头文件ncurses.h 中找到。比

如,你想输出一个具有加粗(BOLD)和加下划线(UNDERLINE)效果的字符变量 ch,

可以使用下面这种方法:

addch(ch | A_BOLD | A_UNDERLINE);

使用 attrset()、attron()、attroff()修饰函数。简而言之,它们将当前的修饰关联于给定

的窗口。一旦设置完成,则在相应窗口中输出的字符都会被修饰,直到关闭窗口。

mvaddch(), waddch() 和 和 mvwaddch()函数

mvaddch()用于将光标移动到指定位置输出字符。

move(row,col); /将光标移动到 row 所指定的行和 col 所指定的列。/

addch(ch);

可以用以下的等价函数取代:

mvaddch(row,col,ch)

waddch()函数和 addch()函数类似。不同的是,waddch()函数是将字符输出到指定窗口的指

定坐标处。(注:addch()将字符输出到标准输出stdscr 上。)

同样的 mvwaddch()函数是把光标移动到指定窗口中的指定位置处输出字符。

printw() 系列函数

这些函数的用法和我们熟悉的printf()函数相似,但增加了可以在屏幕任意位置输出的功能。

printw() 函数和 mvprintw() 函数

这两个函数的绝大部分用法和 printf()函数相同。mvprintw()函数将光标移动到指定的位置,

然后打印内容。如果你想先移动光标,再调用printw()函数,也就是说先调用move()函数,

然后调用 printw()函数。我不知道为什么有些人非要使用这两个函数代替一个函数,当然决

定权在你手里。

printw() 和 函数和 mvwprintw 函数

这两个函数和以上两个函数类似。区别在于这两个函数将在指定的窗口输出内容,而以上两

个函数将内容输出到标准输出stdscr 上。

vwprintw() 函数

这个函数和 vprintf()相似,用于打印变量表中所对应的变量

addstr() 系列函数

addstr()函数用于在指定窗口输出字符串,如同连续使用 addch()函数来输出指定字符串中

的每个字符。实际上,也就是所有 addstr()系列输出函数的事实。addstr()系列函数还包括

mvaddstr()、mvwaddstr()和 waddstr(),它们有着相同的 curses 命名规则和调用方法(如

mvaddstr() 函数就是分别调用了 move()和 addstr()函数)。这个函数集中,还有一个特殊函

数 addnstr(),它需要一个整型参数 n,用来打印字符串中的前 n 个字符。如果这个参数是

负数,addnstr()将会打印整个字符串。

#include<ncurses.h>
#include<string.h>
int main()
{
	char msg[] = "Just a string"; //将要被打印的字符串
	int row,col;      //存储行号和列号的变量,用于指定光标位置
	initscr();		  //进入curses模式
	getmaxyx(stdscr,row,col);		//取得stdscr(标准输出设备)的行数和列数
	mvprintw(row/2,(col-strlen(msg))/2,"%s",msg);  //在屏幕的正中打印字符串
	mvprintw(row-2,0,"this screen has %d rows and %d column\n",row,col);
	printw("Try resizing your window(if possible)and then run this program again");
	refresh();
	getch();
	endwin();

	return 0;
}

提醒

所有这些函数中使用坐标时,先给定y 坐标,再给定 x 坐标,也就是先行后列。因为计算机

字符模式是逐行显示的。很多初学者因为数学上的使用习惯,而错误的先x 后 y。如果你进

行了过多行列坐标的操作,想想看将屏幕分割成几个不同的窗口,然后独立处理每一个单独

窗口的情形

#include<ncurses.h>
int main()
{
	int ch;
	initscr();   //初始化
	raw();		 //禁用行缓冲
	keypad(stdscr,TRUE);  //开启功能键响应模式
	noecho();            //关闭键盘回显
	printw("Type any charater to see it in bold \n");
	ch = getch();  //如果没有调用raw()函数,必须按回车才可以将字符传递给程序

	if(ch == KEY_UP)
		printw("key  up  pressed");

	else
	{
		printw("the pressed key is ");
		attron(A_BOLD);
		printw("%c",ch);
		attroff(A_BOLD);
	}

	refresh();  //将缓冲区的内容打印到显示器上
	getch();    //等待用户输入
	endwin();   //结束curses模式
	return 0;

}

输入函数

如果你的程序只有输出而没有输入,那是非常单调的。让我们来看看处理用户输入的函数。

输入函数也被分为三种:

  1. getch () 系列:读取一个字符的一类函数。
  2. scanw() 系列:按照格式化读取输入的一类函数。
  3. getstr() 系列:读取字符串的一类函数。

getch() 系列函数

这个函数用于从键盘读入一个字符。但是在使用它的时候需要考虑一些微妙的情况:例如你

没有事先调用 cbreak()函数的话,curses 不会连续读取你输入的字符,除非在输入这些字

符之前遇到了换行符或者文末符(EOF)。为了避免这种情况的出现,在需要即时显示输入

字符的程序中,必须先调用cbreak()函数。另外一个比较广泛的做法是使用noecho()函数。

这个函数被调用时,用户输入的字符不会立即显示在屏幕上。cbeak()和 noecho()是两个用

来管理键盘输入的典型函数。

scanw() 系列函数

这些函数用法大体上和 scanf()函数相似。只不过加入了能够在屏幕的任意位置读入格式化

字符串的功能。

scanw() 函数和 mvscanw() 函数

scanw()函数的用法和 sscanf()函数的用法基本相同。实际上,在调用 scanw()函数时,是

调用了 wgetstr()函数,并将 wgetstr()函数处理的数据结果传送到一个 scanw()调用中。

(wgetstr()函数将在本章后半部分介绍,写到这里是为了结构整齐。)

wscanw() 函数和 mvwscanw() 函数

这两个函数的用法和以上两个函数相似。区别在于它们从一个窗口中读取数据。所以,它们

需要指定窗口的指针作为第一个参数。

vwscanw() 函数(vwscanw() )

这个函数和 vprintf()相似。它用于输入变量表中所对应的变量。

getstr() 系列函数

这些函数用于从终端读取字符串。本质上,这个函数执行的任务和连续用 getch()函数读取

字符的功能相同:在遇到回车符、新行符和文末符时将用户指针指向该字符串。

#include<ncurses.h>
#include<string.h>
int main()
{
	char msg[] = "Enter a string";
	char str[80];
	int row,col;
	initscr();
	getmaxyx(stdscr,row,col);
	mvprintw(row/2,(col-strlen(msg))/2,"%s",str);

	getstr(str);
	mvprintw(LINES -2,0,"You Entered:%s",str);
	getch();
	endwin();

	return 0;
}

输出修饰

A_NORMAL 普通字符输出 (不加亮显示)

A_STANDOUT 终端字符最亮

A_UNDERLINE 下划线

A_REVERSE 字符反白显示

A_BLINK 闪动显示

A_DIM 半亮显示

A_BOLD 加亮加粗

A_PROTECT 保护模式

A_INVIS 空白显示模式

A_ALTCHARSET 字符交替

A_CHARTEXT 字符掩盖

color_PAIR(n) 前景、背景色设置

如果你想反白显示字符并同时让字符闪烁。只需要在两种修饰属性间加一个“|”字符就可以:attron(A_REVERSE | A_BLINK);

#include<ncurses.h>
#include<stdlib.h>
int main(int argc,char *argv[])
{
	int ch,prev;
	FILE *fp;
	int goto_prev = FALSE,y,x;
	if(argc != 2)
	{
		printf("Usage:%s<a c file name>\n",argv[0]);
		exit(1);
	}
	fp = fopen(argv[1],"r");   //在这里检测文件是否成功打开
	if(fp == NULL)
	{
		pERROR("Can not open input file");
		exit(1);
	}
	initscr();	  //初始化并进入curses模式
	prev = EOF;
	while((ch = fgetc(fp)) != EOF)
	{
		if(prev =='/' && ch =='*')  //当读到字符"/"和"*"的时候开始修饰
		{
			attron(A_REVERSE|A_BLINK);   //将"/"和"*"以后输出的文字字体加下划线
			goto_prev = TRUE;
		}
		if(goto_prev == TRUE)  //回到"/"和"*"之前开始输出
		{
			getyx(stdscr,y,x);
			move(y,x-1);
			printw("%c%c",'/',ch); //打印实际内容的部分
			ch = 'a';   //避免下次读取变量错误,这里赋一个任意值
			goto_prev = FALSE;  //让这段程序只运行一次
		}
		else 
			printw("%c",ch);
		refresh();    //将缓冲区的内容刷新到屏幕上
		if(prev == '*' && ch == '/')
			attroff(A_REVERSE|A_BLINK);  //当读到字符"/"和"*"的时候关闭修饰
		prev = ch;
	}
	getch();
	endwin();  //结束并退出curses模式
	return 0;
}

attron() 函数和 attrset() 函数之比较

现在我们该讨论讨论 attron()函数和 attrset()函数之间的区别了。attrset()为整个窗口设置一种修饰属性。而 attron()函数只从被调用的地方开始设置。所以 attrset()会覆盖掉你先前为整个窗口设置的所有修饰属性。就像在窗口的开始处开启修饰,在窗口结尾处关闭修饰属性

一样。这两种方法为我们管理输出修饰属性提供了更简单、更富有弹性的方法。但是,如果

你粗心的话,可能会让整个屏幕变得十分杂乱无章,使得函数之间的调用会难以管理。这种

情况,尤其在某些用到菜单系统的程序中十分普遍。所以,事先做好设计,然后按照设计去

实施效果会好得多。另外,你可以经常使用standend()函数关闭所有设置的修饰。这个函数

和 attrset(A_NORMAL)函数的作用是相同的。

attr_get() 函数

attr_get()函数用来取得当前窗口的修饰属性设置以及背景、文字颜色。虽然这个函数不像

上面的那些函数常用。但它却对检测屏幕区域的修饰属性设置很有用。当我们在屏幕输出一

些混合的复杂修饰效果时,这个函数可以告诉我们每一个字符关联的修饰。注意:这个函数

必须在调用了 attrset()或者 attron()之后才能使用。

chgat() 函数

chgar()函数被列在 curs_attr 的 man_page 的最末尾。事实上它是一个很有用的函数。它可

以在不移动光标位置的情况下修改已输出的字符的修饰效果。它从光标当前位置处开始,以

一个整型参数作为修改字符的个数。给这些字符设置某一种修饰属性。

当我们给整型参数赋值为­1 时,它代表一行修饰。如果你想从当前光标位置使整个一行的

输出修饰变为反白显示时,可以这样使用:

chgat(­1, A_REVERSE, 0, NULL);

这个函数经常被用来修改已输出的字符的修饰。当然,你也可以根据自己的需要选择要修改

的起始点和终止点。

#include <ncurses.h>
int main(int argc, char *argv[])
{
	initscr(); /* 进入 curses 模式 */
	start_color(); /* 开启颜色管理功能 */
	init_pair(1, COLOR_CYAN, COLOR_BLACK);
	printw("A Big string which i didn't care to type fully ");
	mvchgat(0, 0, ­1,A_BLINK, 1, NULL);
	/*
	 *第一、二个参数表明了函数开始的位置。
	 *第三个参数是被改变修饰的字符的数目,­1 表示一整行。
	 *第四个参数是被改变的修饰名。
	 *第五个参数是颜色索引。颜色索引已经在init_pair()中被初试化了。
	 *如果用0表示不使用颜色。
	 *最后一个总是 NULL,没什么特殊含义。
	*/
	refresh();
	getch();
	endwin(); /* 结束 curses 模式 */
	return 0;
}

相关阅读

软件界面原型设计工具 Web Axure RP

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow也欢迎大家转载本篇文章。分享知识,造福人民,

Axure教程:明日之子投票界面交互动效制作

最近在追明日之子每天疯狂给妹妹点赞,所以尝试下投票界面的制作,分享给大家,这是我发布的第一篇文章,欢迎各位产品前辈批评指正!预览效

界面设计时该如何面对视觉误差?

编者按:前几天的“蓝黑白金”事件,已经有设计师同学揭秘了误差的原因,木想到今天百度的同学出了升级版的教程,聊聊界面设计过程中,遇到

excel2013工作界面的功能介绍

在Excel众多版本之中,相信很多朋友对2013版本的界面相当的陌生,因为是最新版本嘛,下面是seo实验室小编整理的excel2013工作界面介绍

HTML(css+div)登录界面

<!doctype html> <html> <head> <meta charset="utf-8"> <title>login</title> <style type="text/css"> *{ margin: 0; paddin

分享到:

栏目导航

推荐阅读

热门阅读