linux編程學習筆記(十一) curses CUI介面

來源:互聯網
上載者:User

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:

/*寫一個時間顯示螢幕初始化迴圈顯示時間 並重新整理釋放資源*/#include <curses.h>#include <time.h> //localtime#include <unistd.h> //sleepvoid 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);}}

案例2:
/*
登入介面
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, ...);

#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();}

1 在vi設定編碼
:set enconding=編碼 gd2312 utf-8 ios-8859-1
2 在編譯器指定源檔案的編碼 -finput-charset=gb2312
3 在終端指定編碼
4 系統預設編碼

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

Tags Index: