文档章节

Linux终端彩色打印+终端进度条

狮子的魂
 狮子的魂
发布于 2013/11/21 15:11
字数 1332
阅读 4404
收藏 34

开发的一个应用程序选择了终端界面, 为了使软件稍微好看些, 研究下Linux终端的彩色打印, 并且基于这个彩色打印实现了几种进度条, 在此总结下: (更多的是觉得这个东西挺好玩的... )

一. Linux终端色彩打印:

1. 属性介绍: 

(1). 来自网络的ANSI属性控制码: 

\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               显示光标

(2). 文字背景色彩数字: (颜色范围:40 - 49)

40:    黑色
41:    深红色
42:    绿色
43:    黄色
44:    蓝色
45:    紫色
46:    深绿色
47:    白色

(3). 文字前景色数字: (颜色范围: 30 - 39)

30:    黑色
31:    红色
32:    绿色
33:    黄色
34:    蓝色
35:    紫色
36:    深绿色
37:    白色

2. 使用例子:

Linux终端会解析这些控制码, 并且依据控制码来设置终端的绘制属性, 所以, 只要输出流中包含ANSI控制码就可以工作, 这里使用linux的echo命令来演示:  (你可以使用任何你熟悉的语言来代替...)

(1). 字体红色输出:   

查看上面的ANSI控制码可以知道: \033[30m -- \033[37m是控制前景色, 并且红色使用31表示, 即: 红色ANSI控制码为:  \033[31m

echo -e "\33[31m红色字体\33[0m"     #需要加上-e参数


从\033[31m处开始使用"红色"作为字体的前景色, 后面全部的绘制都使用红色, 直到遇到属性关闭控制码. 所以: 后面使用\033[0m来关闭属性, 要不然终端后面的输入的文字将全部是红色的. 效果图:

(2). 使用多个控制码产生叠加效果:  红色+高亮

echo -e "\033[31m\033[1m红色+高亮\033[0m"   #高亮控制码为: \033[1m

效果:

(3). 红底+白字+高亮+下划线:

echo -e "\033[41m\033[37m\033[1m\033[4m红底+白字+高亮+下划线\033[0m"

效果:


多个控制码可以一起使用, 从而看到叠加的效果, 控制码之间的顺序无所谓, 例如: 上面的高亮和下划线.  其他的控制码就可以自己试试了.


二. Linux终端进度条的实现:

了解了上面的Linux终端彩色打印, 就可以开始做出漂亮的终端进度条了.

 1. 利用\r backspace符来制作进度条:

(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终端进度条制作完毕.


三. 一个C的进度条封装: 

1. progress.h头文件: 

/**
 * 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*/



2. progress.c 源程序:

/**
 * 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);
}



3. tst-pro.c测试程序:

/**
 * 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;
}



4. 测试效果: 

(1). PROGRESS_NUM_STYLE效果:

(2). PROGRESS_CHR_STYLE效果:

(3). PROGRESS_BGC_STYLE效果:

完毕. 代码托管到: http://git.oschina.net/lionsoul/ltpro

© 著作权归作者所有

共有 人打赏支持
狮子的魂

狮子的魂

粉丝 205
博文 11
码字总数 11922
作品 7
深圳
CEO
私信 提问
加载中

评论(7)

Koma
Koma

引用来自“Koma”的评论

怎么顶?是点赞么?

引用来自“狮子的魂”的评论

顶个毛。。。
狮子的魂
狮子的魂

引用来自“Koma”的评论

怎么顶?是点赞么?
顶个毛。。。
Koma
Koma
怎么顶?是点赞么?
狮子的魂
狮子的魂

引用来自“太阳落雨”的评论

特意登陆了来顶下,实在的文章,必须顶~~~

thanks.

太阳落雨
特意登陆了来顶下,实在的文章,必须顶~~~
狮子的魂
狮子的魂

引用来自“-卓然-”的评论

good!

thanks 0
-卓然-
-卓然-
good!
WPS for Linux 社区版 10.1.0.6758 发布

WPS Linux社区版更新说明 WPS公共 新增用户反馈功能 新增升级提示功能 支持中英文语言切换 修复跨模块打开云文档时,提示“账号已下线,请重新登录”问题 修复使用firefox浏览器打开网页时,...

yymxddy
03/11
0
0
WPS for Linux 10.1.0.6757 发布

WPS for Linux 10.1.0.6757 发布 IMCN 4分钟前暂无评论 阅读 6 次 WPS for Linux 10.1.0.6757 发布,新版本发布有DEB、Rpm、Tar.xz以及Snap安装包,您可以根据需要下载deb/rpm/tar.xz/snap格...

IMCN
2018/09/12
0
0
WPS For Linux 6757 社区新版本发布,添加新功能及修复

WPS For Linux 6757社区新版本发布,新功能添加及bug修复,直接列上干货 基础功能 WPS公共 新增snap打包格式,支持snap的系统可直接snap install wps-office来安装 新增用户反馈功能 新增升级...

zhangxm1991
2018/09/12
5.9K
58
【天赢金创】10 条真心有趣的 Linux 命令

在终端工作是一件很有趣的事情。今天,我们将会列举一些有趣得为你带来欢笑的Linux命令。 1. rev 创建一个文件,在文件里面输入几个单词,rev命令会将你写的东西反转输出到控制台。 rev <fil...

第三方支付接口
2015/09/23
47
0
Android 日志分析工具 - LogCatTool

软件下载地址 [V3.6.4] https://download.csdn.net/download/u013662621/10541109 [V3.6.3] http://download.csdn.net/detail/u013662621/9945190 [V3.5.3] http://download.csdn.net/detail......

Surface-pro
2017/04/19
0
1

没有更多内容

加载失败,请刷新页面

加载更多

ehcache

简单介绍 EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认的CacheProvider。Ehcache是一种广泛使用的开 源Java分布式缓存。主要面向通用缓存,Java EE和轻量...

大笨象会跳舞吧
4分钟前
0
0
Android服务2 BindService

MainActivity { class MyService extends Service { public void onCreate() {} public IBinder onBind(Intent intent) { //return new Binder(); retutn new MyBinder(); } public boolean ......

Coding缘
43分钟前
0
0
所有和Java中代理有关的知识点都汇集于此,速进学干货。

对于每一个Java开发来说,代理这个词或多或少都会听说过。你可能听到过的有代理模式、动态代理、反向代理等。那么,到底什么是代理,这么多代理又有什么区别呢。本文就来简要分析一下。 代理...

Java填坑路
49分钟前
1
0
镜像即代码:基于Packer构建阿里云镜像

什么是Packer Packer是HashiCorp推出的一款工具,旨在提供简易的方式自动化构建镜像。通过Packer,你只需要在配置文件中指明镜像构建所需的基本信息及期望安装到镜像中的软件及配置,即可通过...

迷你芊宝宝
50分钟前
1
0
好程序员前端教程之JavaScript闭包和匿名函数的关系详解

好程序员前端教程之JavaScript闭包和匿名函数的关系详解 本文讲的是关于JavaScript闭包和匿名函数两者之间的关系,从匿名函数概念到立即执行函数,最后到闭包。下面一起来看看文章分析,希望...

好程序员IT
58分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部