開發的一個應用程序選擇了終端界面, 爲了使軟件稍微好看些, 研究下Linux終端的彩色打印, 而且基於這個彩色打印實現了幾種進度條, 在此總結下: (更多的是以爲這個東西挺好玩的... ) php
\033[0m 關閉全部屬性 \033[1m 設置高亮度 \033[4m 下劃線 \033[5m 閃爍 \033[7m 反顯 \033[8m 消隱 \033[30m -- \033[37m 設置前景色 \033[40m -- \033[47m 設置背景色 \033[nA 光標上移n行 \033[nB 光標下移n行 \033[nC 光標右移n列 \033[nD 光標左移n列 \033[y;H 設置光標位置 \033[2J 清屏 \033[K 清除從光標到行尾的內容 \033[s 保存光標位置 \033[u 恢復光標位置 \033[?25l 隱藏光標 \033[?25h 顯示光標
40: 黑色
41: 深紅色
42: 綠色
43: 黃色
44: 藍色
45: 紫色
46: 深綠色
47: 白色 linux
30: 黑色
31: 紅色
32: 綠色
33: 黃色
34: 藍色
35: 紫色
36: 深綠色
37: 白色 git
Linux終端會解析這些控制碼, 而且依據控制碼來設置終端的繪製屬性, 因此, 只要輸出流中包含ANSI控制碼就能夠工做, 這裏使用linux的echo命令來演示: (你能夠使用任何你熟悉的語言來代替...) shell
(1). 字體紅色輸出: 網絡
查看上面的ANSI控制碼能夠知道: \033[30m -- \033[37m是控制前景色, 而且紅色使用31表示, 即: 紅色ANSI控制碼爲: \033[31m 測試
echo -e "\33[31m紅色字體\33[0m" #須要加上-e參數
從\033[31m處開始使用"紅色"做爲字體的前景色, 後面所有的繪製都使用紅色, 直到遇到屬性關閉控制碼. 因此: 後面使用\033[0m來關閉屬性, 要否則終端後面的輸入的文字將所有是紅色的. 效果圖: 字體
(2). 使用多個控制碼產生疊加效果: 紅色+高亮 spa
echo -e "\033[31m\033[1m紅色+高亮\033[0m" #高亮控制碼爲: \033[1m
效果: .net
(3). 紅底+白字+高亮+下劃線: code
echo -e "\033[41m\033[37m\033[1m\033[4m紅底+白字+高亮+下劃線\033[0m"
效果:
多個控制碼能夠一塊兒使用, 從而看到疊加的效果, 控制碼之間的順序無所謂, 例如: 上面的高亮和下劃線. 其餘的控制碼就能夠本身試試了.
瞭解了上面的Linux終端彩色打印, 就能夠開始作出漂亮的終端進度條了.
(1). 一個php例子以下: (注意, php要使用printf, echo沒用的)
<?php for ($i = 0; $i <= 50; $i++) { printf("mprogress: %d%% %s\r", $i * 2, str_repeat('#',$i) ); usleep(1000 * 100); } echo "\n", "Done.\n"; ?>
運行效果以下:
(2). 加上色彩:
(3). 進一步美化, 使用背景而且使用空格代替'#'字符:
<?php for ($i = 0; $i <= 50; $i++) { printf("mprogress: \033[41m\033[1m %d%% %s\r\033[0m", $i * 2, str_repeat(' ',$i) ); usleep(1000 * 100); } echo "\n", "Done.\n"; ?>
效果:
哈, 效果還不錯呢.
(4). 終極美化, 將光標隱藏:
這個只要在裏面加上隱藏光標的ANSI控制碼就ok了, 不過記得要在後面將光標回覆顯示, 要否則後面終端就看不到光標了:
<?php for ($i = 0; $i <= 50; $i++) { printf("\033[?25lmprogress: \033[41m\033[1m %d%% %s\r\033[0m", $i * 2, str_repeat(' ',$i) ); usleep(1000 * 100); } printf("\nDone.\n\033[?25h"); ?>
效果:
到此Linux終端進度條製做完畢.
/** * linux terminal progress bar (no thread safe). * @package progress.h. * * @author chenxin <chenxin619315@gmail.com> */ #ifndef progress_h #define progress_h #include <stdio.h> typedef struct { char chr; /*tip char*/ char *title; /*tip string*/ int style; /*progress style*/ int max; /*maximum value*/ float offset; char *pro; } progress_t; #define PROGRESS_NUM_STYLE 0 #define PROGRESS_CHR_STYLE 1 #define PROGRESS_BGC_STYLE 2 extern void progress_init(progress_t *, char *, int, int); extern void progress_show(progress_t *, float); extern void progress_destroy(progress_t *); #endif /*ifndef*/
/** * linux terminal progress bar (no thread safe). * @package progress.c * * @author chenxin <chenxin619315@gmail.com> */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "progress.h" /** * initialize the progress bar. * @max = 0 * @val = 0 * * @param style * @param tip words. */ extern void progress_init( progress_t *bar, char *title, int max, int style) { bar->chr = '#'; bar->title = title; bar->style = style; bar->max = max; bar->offset = 100 / (float)max; bar->pro = (char *) malloc(max+1); if ( style == PROGRESS_BGC_STYLE ) memset(bar->pro, 0x00, max+1); else { memset(bar->pro, 32, max); memset(bar->pro+max, 0x00, 1); } } extern void progress_show( progress_t *bar, float bit ) { int val = (int)(bit * bar->max); switch ( bar->style ) { case PROGRESS_NUM_STYLE: printf("\033[?25l\033[31m\033[1m%s%d%%\033[?25h\033[0m\r", bar->title, (int)(bar->offset * val)); fflush(stdout); break; case PROGRESS_CHR_STYLE: memset(bar->pro, '#', val); printf("\033[?25l\033[31m\033[1m%s[%-s] %d%%\033[?25h\033[0m\r", bar->title, bar->pro, (int)(bar->offset * val)); fflush(stdout); break; case PROGRESS_BGC_STYLE: memset(bar->pro, 32, val); printf("\033[?25l\033[31m\033[1m%s\033[41m %d%% %s\033[?25h\033[0m\r", bar->title, (int)(bar->offset * val), bar->pro); fflush(stdout); break; } } //destroy the the progress bar. extern void progress_destroy(progress_t *bar) { free(bar->pro); }
/** * program bar test program. * * @author chenxin <chenxin619315@gmail.com> */ #include "progress.h" #include <unistd.h> int main(int argc, char *argv[] ) { progress_t bar; //progress_init(&bar, "", 50, PROGRESS_NUM_STYLE); progress_init(&bar, "", 50, PROGRESS_CHR_STYLE); //progress_init(&bar, "", 50, PROGRESS_BGC_STYLE); int i; for ( i = 0; i <= 50; i++ ) { progress_show(&bar, i/50.0f); sleep(1); } printf("\n+-Done\n"); progress_destroy(&bar); return 0; }
(1). PROGRESS_NUM_STYLE效果:
(2). PROGRESS_CHR_STYLE效果:
(3). PROGRESS_BGC_STYLE效果:
完畢. 代碼託管到: http://git.oschina.net/lionsoul/ltpro