Linux终端图形库Curses简介和实例分析
Linux终端图形库Curses简介和实例分析
2008-12-2 13:40|查看数: 1322
随着电脑知识的普及, 越来越多的电脑爱好者开始了解和使⽤Linux.。Linux的轻松⾃由之风给了我们不同的感受。但是我们不能满⾜于基本的命令和KDE, Gnome等⽤户界⾯的操作. 我们要⼲什么? 编程, 对, 编程! 对于编程爱好者, Linux有着很好的编程环境: gcc(GNU Compiler Collection)能够编译C, C++, Java等很多种语⾔, ⽽且Linux环境下有很多函数库可以调⽤.了解⼀些这些函数库的使⽤, 会给你的编程⼯具箱⾥增加许多有⽤的⼯具. 今天, 就让我们来认识⼀下curses --- 它不是什么中世纪巫婆的咒语,⽽是⼀个在Linux/Unix下⼴泛应⽤的图形函数库.
以前学过TC2.0的朋友肯定还记得TC⾥边有⼀个图形库BGI(Borland Graphics Interface, 还记得那个头⽂件吗:). ⽤它我们可以绘制在DOS下的⽤户界⾯和漂亮的图形. ⽽Linux/Unix编程给⼈的感觉就⽐较"cool"⼀点, 好像Linux编程都是在⿊⿊的终端下进⾏的.确实是这样,许多Linux⾼⼿都喜欢在终端⽅式下⼯作, 熟悉了⼀些命令以后,这样的⼯作⽅式效率还是很⾼的. 但是长久地看着⿊⿊的屏幕难免让⼈感到厌倦, 特别是像我这样接触Linux不久的菜鸟:) 有没有⼀种⼯具能让我们在Linux下编出好看的图形呢? 答案是肯定的, 它就是curses!
curses的名字起源于"cursor optimization",即光标优化. 它最早由有美国伯克利⼤学的Bill Joy和Ken Arnold编写的, ⽤来处理⼀个游戏rogue的屏幕显⽰. 后来贝尔实验室的Mark Horton在System III Unix中重新编写了curses. 现在⼏乎所有的Unix, Linux 操作系统都带了curses函数库, curses也加⼊了对⿏标的⽀持, ⼀些菜单和⾯板的处理. 可以说, curses是Linux终端图形编程的不⼆选择(⽐如著名的⽂字编辑器 vi 就是基于curses编的)
OK, 闲话少说,现在我们开始进⼊正题:
⾸先我们应该了解, 在终端使⽤使⽤的屏幕模式是基于⽂本的. 所以在开始使⽤curses前, 需要⽤initscr()函数初始化屏幕. 对应的,程序结束需要调⽤endwin();函数来关闭curses状态.
有了这个概念, 我们就可以来写著名的"Hello, world!"之curses版了:
/*-----------------------------------------------------------------
A very simple example of curses programming
coder: jellen
date: 3-26-2004
----------------------------------------------------------------*/
#include
int main()
{
initscr();
box(stdscr, ACS_VLINE, ACS_HLINE); /*draw a box*/
move(LINES/2, COLS/2); /*move the cursor to the center*/
waddstr(stdscr, "Hello, world!");
refresh();
getch();
endwin();
return 0;
}
呵呵, 刚才忘了说了. 我们调⽤curses库⼀般是⽤C语⾔的(没什么奇怪, C可以说是Linux的官⽅语⾔, 不过你也可以⽤C++或Python等语⾔调⽤curses的, 这⽆关紧要). 假设我们把这个程序保存为 hello.c
不过不要急着⽤gcc -o hello hello.c去编译运⾏(我知道你会⽤gcc:) 那样是不能通过编译的. 因为curses库不在标准路径上, 所以我们要加上 -lcurses连接选项, 像这样:
gcc -o hello hello.c -lcurses
现在你⽤ ./hello 运⾏⼀下程序看看,是不是出现了你所期望的窗⼝.
现在我们来⼀⾏⾏分析⼀下代码.
#include /*这是每个 curses 程序都必须包含的头⽂件,表明使⽤了curses库*/
然后主函数中第⼀句initscr();初始化了屏幕, 使之开始进⼊curses图形化⼯作⽅式.
其实我们现在没有⾃⼰建⽴窗⼝, ⽤的是标准屏幕 stdscr(就象C⾥⾯标准输⼊stdin, 标准输出stdout⼀
个概念), 它就是我们⾯前的电脑屏幕(不过现在还是⿊⿊的)
下⾯⼀句: box(stdscr, ACS_VLINE, ACS_HLINE); 画了⼀个框. 有了这个框我们才有"窗体"的感觉. stdscr就是标准屏幕, ACS_VLINE和ACS_HLINE代表构成⽅框两边的基本元素, 你也可以⽤ ''''|''''和''''-''''代替, 不过可能没有ACS_VLINE, ACS_HLINE 好看了.
好看了.
move(LINES/2, COLS/2);
waddstr(stdscr, "Hello, world!");
这两句是把光标移到屏幕中间, 然后输出我们的"Hello, world!"
LINES 和 COLS是curses定义的宏, 代表当前屏幕的最⼤⾏数和列数. waddstr()函数的作⽤是在stdscr上打印字符串"hello, world!"
屏幕分物理屏幕(我们所看到的)和逻辑屏幕(在内存中的), 我们调⽤函数时修改的是逻辑屏幕,它不会在当前物理屏幕上显⽰出来.所以现在屏幕上还是什么也没有, 需要调⽤refresh()把我们对逻辑屏幕的改动在物理屏幕(显⽰器)上显⽰出来. 然后⽤getch()让屏幕暂停⼀下.
最后调⽤endwin()结束curses, 恢复原来的屏幕.
好了, 我们完成了第⼀个例⼦的分析. 是不是挺简单的?
不过不尽如⼈意的是屏幕还是那个样⼦, 没有什么⾊彩. 要加⾊彩? 那也是挺容易的: ⾸先⽤start_color()函数开启颜⾊模式, 然后设置我们要的颜⾊就⾏了.
curses⾥的颜⾊是配对的, 要⼀个背景⾊对⼀个前景⾊. 使⽤之前⽤init_pair()初始化.
⽐如init_pair(1, COLOR_BLUE, COLOR_GREEN);就定义了⼀组颜⾊, COLOR_BLUE为前景⾊, COLOR_GREEN为背景⾊. 1是它们的标记号码(供其他函数调⽤时使⽤) 我们来看⼀个简单的例⼦:
/*--------------------------------------------------------------
A simple curses color demo program
Coder: jellen
Date: 3-26-2004
-------------------------------------------------------------*/
#include
int main()
{
initscr(); /*初始化屏幕*/
if(start_color() == OK) /*开启颜⾊*/
{
init_pair(1, COLOR_RED, COLOR_GREEN); /*建⽴⼀个颜⾊对*/
attron(COLOR_PAIR(1)); /*开启字符输出颜⾊*/
move(LINES/2, COLS/2);
waddstr(stdscr, "Yet another Hello, world!");
attroff(COLOR_PAIR(1)); /*关闭颜⾊显⽰*/
refresh();
}
else
linux vi命令详解菜鸟教学{
waddstr(stdscr, "Can not init color");
refresh();
}
endwin(); /*关闭curses状态*/
return 0;
}
这个程序假如保存为color.c
那么你可以这样编译了: gcc -o color color.c -lcurses
⽤./color⼀运⾏个彩⾊的字? 呵呵, 虽然不好看, 但是说不定你⾃⼰以后可以⽤curses写出精美的程序。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论