indicators

indicators

C++进度条和加载动画库

indicators是一个C++库,提供线程安全的进度条和加载动画。支持多种进度条样式,包括基本、不确定、方块、多进度和动态进度条。该库为头文件式,使用简便,并可自定义Unicode、颜色和字体等选项。适用于需在命令行界面显示进度的C++应用。

indicators进度条多线程C++命令行界面Github开源项目
<p align="center"> <img height="70" src="https://yellow-cdn.veclightyear.com/2b54e442/3e452dfa-a6ef-4826-92f7-75a45c45991a.png"/> </p> <p align="center"> <a href="https://www.codacy.com/manual/p-ranav/indicators?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=p-ranav/indicators&amp;utm_campaign=Badge_Grade"> <img src="https://api.codacy.com/project/badge/Grade/93401e73f250407cb32445afec4e3e99" alt="codacy"/> </a> <a href="https://github.com/p-ranav/indicators/blob/master/LICENSE"> <img src="https://yellow-cdn.veclightyear.com/2b54e442/129bc4ef-5677-4263-9c80-3780f858e628.svg" alt="license"/> </a> <img src="https://yellow-cdn.veclightyear.com/2b54e442/f2b73ed6-f7b0-44e7-bd47-149517454e72.svg?cacheSeconds=2592000" alt="version"/> </p> <p align="center"> <img src="https://yellow-cdn.veclightyear.com/2b54e442/da17b934-f144-463b-9506-559f45dbe72f.gif"/> </p>

亮点

  • 线程安全的进度条和加载动画
  • 仅头文件库。获取include/indicators的副本。
  • 单头文件版本在single_include/indicators中。
  • 上述GIF的源代码可以在这里找到
  • MIT许可证

目录

基本进度条

要在应用程序中引入进度条,请包含indicators/progress_bar.hpp并创建一个ProgressBar对象。以下是进度条的一般结构:

{前缀} {开始} {填充} {引导} {剩余} {结束} {百分比} [{已用时间}<{剩余时间}] {后缀}
         ^^^^^^^^^^^^^ 条宽 ^^^^^^^^^^^^^^^   

ProgressBar中的进度量以size_t类型维护,范围为[0, 100]。当进度达到100时,进度完成。

从应用程序级代码,有两种方法可以更新这个进度:

使用bar.tick()更新进度

你可以使用bar.tick()更新进度条,它每次将进度增加恰好1%

<p align="center"> <img src="https://yellow-cdn.veclightyear.com/2b54e442/27c8bf7f-3f75-4a22-8cb1-787fc1fdba95.gif"/> </p>
#include <indicators/progress_bar.hpp> #include <thread> #include <chrono> int main() { using namespace indicators; ProgressBar bar{ option::BarWidth{50}, option::Start{"["}, option::Fill{"="}, option::Lead{">"}, option::Remainder{" "}, option::End{"]"}, option::PostfixText{"正在提取归档"}, option::ForegroundColor{Color::green}, option::FontStyles{std::vector<FontStyle>{FontStyle::bold}} }; // 更新进度条状态 while (true) { bar.tick(); if (bar.is_completed()) break; std::this_thread::sleep_for(std::chrono::milliseconds(100)); } return 0; }

上述代码将打印一个进度条,每100毫秒增加1%,从0%到100%。

使用bar.set_progress(value)更新进度

如果你希望以离散步骤控制进度条的进度,可以考虑使用bar.set_progress(value)。例如:

<p align="center"> <img src="https://yellow-cdn.veclightyear.com/2b54e442/5bef2f46-10a8-4dd6-a5ee-a6c19c2d9ee5.gif"/> </p>
#include <chrono> #include <indicators/cursor_control.hpp> #include <indicators/progress_bar.hpp> #include <thread> int main() { using namespace indicators; // 隐藏光标 show_console_cursor(false); ProgressBar bar{ option::BarWidth{50}, option::Start{"["}, option::Fill{"■"}, option::Lead{"■"}, option::Remainder{"-"}, option::End{" ]"}, option::PostfixText{"正在加载依赖项 1/4"}, option::ForegroundColor{Color::cyan}, option::FontStyles{std::vector<FontStyle>{FontStyle::bold}} }; // 更新进度条状态 bar.set_progress(10); // 完成10% // 执行一些工作 std::this_thread::sleep_for(std::chrono::milliseconds(800)); bar.set_option(option::PostfixText{"正在加载依赖项 2/4"}); bar.set_progress(30); // 完成30% // 执行更多工作 std::this_thread::sleep_for(std::chrono::milliseconds(700)); bar.set_option(option::PostfixText{"正在加载依赖项 3/4"}); bar.set_progress(65); // 完成65% // 执行最后一部分工作 std::this_thread::sleep_for(std::chrono::milliseconds(900)); bar.set_option(option::PostfixText{"依赖项已加载!"}); bar.set_progress(100); // 全部完成 // 显示光标 show_console_cursor(true); return 0; }

显示已用时间/剩余时间

indicators中的所有进度条和加载动画都支持显示已用时间和剩余时间。受Python的tqdm模块启发,这个计时器的格式是[{已用时间}<{剩余时间}]

<p align="center"> <img src="https://yellow-cdn.veclightyear.com/2b54e442/e6d82a6b-c3b6-43f4-953a-07074d2ef3a0.gif"/> </p>
#include <chrono> #include <indicators/cursor_control.hpp> #include <indicators/progress_bar.hpp> #include <thread> int main() { using namespace indicators; // 隐藏光标 show_console_cursor(false); indicators::ProgressBar bar{ option::BarWidth{50}, option::Start{" ["}, option::Fill{"█"}, option::Lead{"█"}, option::Remainder{"-"}, option::End{"]"}, option::PrefixText{"训练注视网络 👀"}, option::ForegroundColor{Color::yellow}, option::ShowElapsedTime{true}, option::ShowRemainingTime{true}, option::FontStyles{std::vector<FontStyle>{FontStyle::bold}} }; // 更新进度条状态 while (true) { bar.tick(); if (bar.is_completed()) break; std::this_thread::sleep_for(std::chrono::milliseconds(1000)); } // 显示光标 show_console_cursor(true); return 0; }

不确定进度条

你可能有一个需要进度条但最大进度未知的用例,例如,你正在从一个没有公布总字节数的远程服务器下载内容。

在这种情况下使用indicators::IndeterminateProgressBarIndeterminateProgressBar类似于常规进度条,只是要达到的总进度是未知的。这种进度条的tick可以无限运行。

当你知道进度完成时,只需调用bar.mark_as_completed()

<p align="center"> <img src="https://yellow-cdn.veclightyear.com/2b54e442/170652fe-3dc5-4703-a117-7220a645ed36.gif"/> </p>
#include <chrono> #include <indicators/indeterminate_progress_bar.hpp> #include <indicators/cursor_control.hpp> #include <indicators/termcolor.hpp> #include <thread> int main() { indicators::IndeterminateProgressBar bar{ indicators::option::BarWidth{40}, indicators::option::Start{"["}, indicators::option::Fill{"·"}, indicators::option::Lead{"<==>"}, indicators::option::End{"]"}, indicators::option::PostfixText{"检查更新"}, indicators::option::ForegroundColor{indicators::Color::yellow}, indicators::option::FontStyles{ std::vector<indicators::FontStyle>{indicators::FontStyle::bold}} }; indicators::show_console_cursor(false); auto job = [&bar]() { std::this_thread::sleep_for(std::chrono::milliseconds(10000)); bar.mark_as_completed(); std::cout << termcolor::bold << termcolor::green << "系统已是最新版本!\n" << termcolor::reset; }; std::thread job_completion_thread(job); // 更新进度条状态 while (!bar.is_completed()) { bar.tick(); std::this_thread::sleep_for(std::chrono::milliseconds(100)); } job_completion_thread.join(); indicators::show_console_cursor(true); return 0; }

块进度条

你是否需要使用Unicode块元素的平滑块进度条?使用BlockProgressBar而不是ProgressBar。感谢这篇博客文章使BlockProgressBar成为该库的一个简单添加。

<p align="center"> <img src="https://yellow-cdn.veclightyear.com/2b54e442/7d1309cb-bc74-4963-8223-44ecee1f306e.gif"/> </p>
#include <indicators/block_progress_bar.hpp> #include <indicators/cursor_control.hpp> #include <thread> #include <chrono> int main() { using namespace indicators; // 隐藏光标 show_console_cursor(false); BlockProgressBar bar{ option::BarWidth{80}, option::Start{"["}, option::End{"]"}, option::ForegroundColor{Color::white} , option::FontStyles{std::vector<FontStyle>{FontStyle::bold}} }; // 更新进度条状态 auto progress = 0.0f; while (true) { bar.set_progress(progress); progress += 0.25f; if (bar.is_completed()) break; std::this_thread::sleep_for(std::chrono::milliseconds(50)); } // 显示光标 show_console_cursor(true); return 0; }

多重进度

indicators支持使用MultiProgress类模板管理多个进度条。

template <typename Indicator, size_t count> class MultiProgress是一个类模板,它持有多个进度条的引用,并提供一个安全的接口来更新每个进度条的状态。MultiProgress适用于ProgressBarBlockProgressBar类。

如果你在编译时知道要管理的进度条数量,请使用此类。

以下是一个管理三个ProgressBar对象的MultiProgress对象的示例。

<p align="center"> <img src="https://yellow-cdn.veclightyear.com/2b54e442/c21f5870-557f-45a5-8a1d-6f95ca07fa16.gif"/> </p>
#include <indicators/multi_progress.hpp> #include <indicators/progress_bar.hpp> int main() { using namespace indicators; // 配置第一个进度条 ProgressBar bar1{ option::BarWidth{50}, option::Start{"["}, option::Fill{"■"}, option::Lead{"■"}, option::Remainder{" "}, option::End{" ]"}, option::ForegroundColor{Color::yellow}, option::ShowElapsedTime{true}, option::ShowRemainingTime{true}, option::PrefixText{"进度条 #1 "}, option::FontStyles{std::vector<FontStyle>{FontStyle::bold}} }; // 配置第二个进度条 ProgressBar bar2{ option::BarWidth{50}, option::Start{"["}, option::Fill{"="}, option::Lead{">"}, option::Remainder{" "}, option::End{" ]"}, option::ForegroundColor{Color::cyan}, option::ShowElapsedTime{true}, option::ShowRemainingTime{true}, option::PrefixText{"进度条 #2 "}, option::FontStyles{std::vector<FontStyle>{FontStyle::bold}} }; // 配置第三个进度条 indicators::ProgressBar bar3{ option::BarWidth{50}, option::Start{"["}, option::Fill{"#"}, option::Lead{"#"}, option::Remainder{" "}, option::End{" ]"}, option::ForegroundColor{Color::red}, option::ShowElapsedTime{true}, option::ShowRemainingTime{true}, option::PrefixText{"进度条 #3 "}, option::FontStyles{std::vector<FontStyle>{FontStyle::bold}} }; // 构造 MultiProgress 对象 indicators::MultiProgress<indicators::ProgressBar, 3> bars(bar1, bar2, bar3); std::cout << "多个进度条:\n"; auto job1 = [&bars]() { while (true) { bars.tick<0>(); if (bars.is_completed<0>()) break; std::this_thread::sleep_for(std::chrono::milliseconds(100)); } }; auto job2 = [&bars]() { while (true) { bars.tick<1>(); if (bars.is_completed<1>()) break; std::this_thread::sleep_for(std::chrono::milliseconds(200)); } }; auto job3 = [&bars]() { while (true) { bars.tick<2>(); if (bars.is_completed<2>()) break; std::this_thread::sleep_for(std::chrono::milliseconds(60)); } }; std::thread first_job(job1); std::thread second_job(job2); std::thread third_job(job3); first_job.join(); second_job.join(); third_job.join(); return 0; }

DynamicProgress

DynamicProgress 是一个容器类,类似于 MultiProgress,用于管理多个进度条。顾名思义,使用 DynamicProgress,您可以动态添加新的进度条。

要添加新的进度条,调用 bars.push_back(new_bar)。这个调用将返回追加的条的索引。然后您可以使用索引运算符引用这个条,例如 bars[4].set_progress(55)

如果您在编译时不知道进度条的数量,请使用这个类。

下面是一个 DynamicProgress 对象的示例,它管理六个 ProgressBar 对象。其中三个条是动态添加的。

<p align="center"> <img src="https://yellow-cdn.veclightyear.com/2b54e442/4e8b23f9-1aee-4380-ab77-006ef0f73c6d.gif"/> </p>
#include <indicators/dynamic_progress.hpp> #include <indicators/progress_bar.hpp> using namespace indicators; int main() { auto bar1 = std::make_unique<ProgressBar>(option::BarWidth{50}, option::ForegroundColor{Color::red}, option::ShowElapsedTime{true}, option::ShowRemainingTime{true}, option::PrefixText{"5c90d4a2d1a8: 下载中 "}, indicators::option::FontStyles{ std::vector<indicators::FontStyle>{indicators::FontStyle::bold}}); auto bar2 = std::make_unique<ProgressBar>(option::BarWidth{50}, option::ForegroundColor{Color::yellow}, option::ShowElapsedTime{true}, option::ShowRemainingTime{true}, option::PrefixText{"22337bfd13a9: 下载中 "}, indicators::option::FontStyles{ std::vector<indicators::FontStyle>{indicators::FontStyle::bold}}); auto bar3 = std::make_unique<ProgressBar>(option::BarWidth{50}, option::ForegroundColor{Color::green}, option::ShowElapsedTime{true}, option::ShowRemainingTime{true}, option::PrefixText{"10f26c680a34: 下载中 "}, indicators::option::FontStyles{ std::vector<indicators::FontStyle>{indicators::FontStyle::bold}}); auto bar4 = std::make_unique<ProgressBar>(option::BarWidth{50}, option::ForegroundColor{Color::white}, option::ShowElapsedTime{true}, option::ShowRemainingTime{true}, option::PrefixText{"6364e0d7a283: 下载中 "}, indicators::option::FontStyles{ std::vector<indicators::FontStyle>{indicators::FontStyle::bold}}); auto bar5 = std::make_unique<ProgressBar>(option::BarWidth{50}, option::ForegroundColor{Color::blue}, option::ShowElapsedTime{true}, option::ShowRemainingTime{true}, option::PrefixText{"ff1356ba118b: 下载中 "}, indicators::option::FontStyles{ std::vector<indicators::FontStyle>{indicators::FontStyle::bold}}); auto bar6 = std::make_unique<ProgressBar>(option::BarWidth{50}, option::ForegroundColor{Color::cyan}, option::ShowElapsedTime{true}, option::ShowRemainingTime{true}, option::PrefixText{"5a17453338b4: 下载中 "}, indicators::option::FontStyles{ std::vector<indicators::FontStyle>{indicators::FontStyle::bold}}); std::cout << termcolor::bold << termcolor::white << "拉取镜像 foo:bar/baz\n"; // 构造包含3个进度条。我们稍后会再添加3个 DynamicProgress<ProgressBar> bars(bar1, bar2, bar3); // 完成时不隐藏进度条 bars.set_option(option::HideBarWhenComplete{false}); std::thread fourth_job, fifth_job, sixth_job; auto job4 = [&bars](size_t i) { while (true) { bars[i].tick(); if (bars[i].is_completed()) { bars[i].set_option(option::PrefixText{"6364e0d7a283: 拉取完成 "}); bars[i].mark_as_completed(); break; } std::this_thread::sleep_for(std::chrono::milliseconds(50)); } }; auto job5 = [&bars](size_t i) { while (true) { bars[i].tick(); if (bars[i].is_completed()) { bars[i].set_option(option::PrefixText{"ff1356ba118b: 拉取完成 "}); bars[i].mark_as_completed(); break; } std::this_thread::sleep_for(std::chrono::milliseconds(100)); } }; auto job6 = [&bars](size_t i) { while (true) { bars[i].tick(); if (bars[i].is_completed()) { bars[i].set_option(option::PrefixText{"5a17453338b4: 拉取完成 "}); bars[i].mark_as_completed(); break; } std::this_thread::sleep_for(std::chrono::milliseconds(40)); } }; auto job1 = [&bars, &bar6, &sixth_job, &job6]() { while (true) { bars[0].tick(); if (bars[0].is_completed()) { bars[0].set_option(option::PrefixText{"5c90d4a2d1a8: 拉取完成 "}); // bar1 完成,添加 bar6 auto i = bars.push_back(std::move(bar6)); sixth_job = std::thread(job6, i); sixth_job.join(); break; } std::this_thread::sleep_for(std::chrono::milliseconds(140)); } }; auto job2 = [&bars, &bar5, &fifth_job, &job5]() { while (true) { bars[1].tick(); if (bars[1].is_completed()) { bars[1].set_option(option::PrefixText{"22337bfd13a9: 拉取完成 "}); // bar2 完成,添加 bar5 auto i = bars.push_back(std::move(bar5)); fifth_job = std::thread(job5, i); fifth_job.join(); break; } std::this_thread::sleep_for(std::chrono::milliseconds(25)); } }; auto job3 = [&bars, &bar4, &fourth_job, &job4]() { while (true) { bars[2].tick(); if (bars[2].is_completed()) { bars[2].set_option(option::PrefixText{"10f26c680a34: 拉取完成 "}); // bar3 完成,添加 bar4 auto i = bars.push_back(std::move(bar4)); fourth_job = std::thread(job4, i); fourth_job.join(); break; } std::this_thread::sleep_for(std::chrono::milliseconds(50)); } }; std::thread first_job(job1); std::thread second_job(job2); std::thread third_job(job3); third_job.join(); second_job.join(); first_job.join(); std::cout << termcolor::bold << termcolor::green << "✔ 下载完成镜像 foo/bar:baz" << std::endl; std::cout << termcolor::reset; return 0; }

在上面的代码中,注意选项 bars.set_option(option::HideBarWhenComplete{true});。是的,您可以通过将此选项设置为 true 来在进度条完成时隐藏它们。如果这样做,上面的例子将看起来像这样:

<p align="center"> <img src="https://yellow-cdn.veclightyear.com/2b54e442/79e2da78-59d5-4e2b-9329-8faa6ee197af.gif"/> </p>

进度旋转器

要在应用程序中引入进度旋转器,包含 indicators/progress_spinner.hpp 并创建一个 ProgressSpinner 对象。以下是进度旋转器的一般结构:

{前缀} {旋转器} {百分比} [{已用时间}<{剩余时间}] {后缀}

ProgressSpinner 有一个字符串向量:spinner_states。每次更新时,旋转器将从这个序列中选择下一个字符串打印到控制台。旋转器状态可以类似于进度条进行更新:使用 tick()set_progress(value)

<p align="center"> <img src="https://yellow-cdn.veclightyear.com/2b54e442/389220a4-33a6-48ba-b287-f86eae194c4b.gif"/> </p>
#include <indicators/progress_spinner.hpp> int main() { using namespace indicators; indicators::ProgressSpinner spinner{ option::PostfixText{"正在检查凭证"}, option::ForegroundColor{Color::yellow}, option::SpinnerStates{std::vector<std::string>{"⠈", "⠐", "⠠", "⢀", "⡀", "⠄", "⠂", "⠁"}}, option::FontStyles{std::vector<FontStyle>{FontStyle::bold}} }; // 更新旋转器状态 auto job = [&spinner]() { while (true) { if (spinner.is_completed()) { spinner.set_option(option::ForegroundColor{Color::green}); spinner.set_option(option::PrefixText{"✔"}); spinner.set_option(option::ShowSpinner{false}); spinner.set_option(option::ShowPercentage{false}); spinner.set_option(option::PostfixText{"已认证!"}); spinner.mark_as_completed(); break; } else spinner.tick(); std::this_thread::sleep_for(std::chrono::milliseconds(40)); } }; std::thread thread(job); thread.join(); return 0; }

递减进度

indicators 允许您轻松控制进度方向,即递增或递减进度,使用 option::ProgressType。要编程一个倒计时进度条,使用 option::ProgressType::decremental

<p align="center"> <img src="https://yellow-cdn.veclightyear.com/2b54e442/e5a139e4-7a8b-4c64-8b92-8d82f26784c4.gif"/> </p>
#include <chrono> #include <indicators/progress_bar.hpp> #include <thread> using namespace indicators; int main() { ProgressBar bar{option::BarWidth{50}, option::ProgressType{ProgressType::decremental}, option::Start{"["}, option::Fill{"■"}, option::Lead{"■"}, option::Remainder{"-"}, option::End{"]"}, option::PostfixText{"正在还原系统恢复"}, option::ForegroundColor{Color::yellow}, option::FontStyles{std::vector<FontStyle>{FontStyle::bold}}}; // 更新进度条状态 while (true) { bar.tick(); if (bar.is_completed()) break; std::this_thread::sleep_for(std::chrono::milliseconds(100)); } std::cout << termcolor::bold << termcolor::white << "任务成功失败\n" << termcolor::reset; return 0; }

使用可迭代对象

如果您想使用进度条来指示在迭代可迭代对象(例如数字列表)时的进度,可以通过使用 option::MaxProgress 来实现:

<p align="center"> <img src="https://yellow-cdn.veclightyear.com/2b54e442/00dcd8b2-55e3-43bd-a1f8-61fe404b7d6d.gif"/> </p>
#include <chrono> #include <indicators/block_progress_bar.hpp> #include <indicators/cursor_control.hpp> #include <thread> int main() { // 隐藏光标 indicators::show_console_cursor(false); // 随机数字列表 std::vector<size_t> numbers; for (size_t i = 0; i < 1259438; ++i) { numbers.push_back(i); } using namespace indicators; BlockProgressBar bar{ option::BarWidth{80}, option::ForegroundColor{Color::white}, option::FontStyles{ std::vector<FontStyle>{FontStyle::bold}}, option::MaxProgress{numbers.size()} }; std::cout << "迭代数字列表(大小 = " << numbers.size() << ")\n"; std::vector<size_t> result; for (size_t i = 0; i < numbers.size(); ++i) { // 执行一些计算 result.push_back(numbers[i] * numbers[i]); // 显示迭代作为后缀文本 bar.set_option(option::PostfixText{ std::to_string(i) + "/" + std::to_string(numbers.size()) }); // 更新进度条 bar.tick(); } bar.mark_as_completed(); // 显示光标 indicators::show_console_cursor(true); return 0; }

Unicode 支持

indicators 支持进度条中的多字节 Unicode 字符。

如果设置了 option::BarWidth,库会尽量遵守这个设置。在填充进度条时,如果下一个 Fill 字符串的显示宽度会超过进度条宽度,那么库会用 ' ' 空格字符填充进度条的剩余部分。

以下是一些进度条的示例,每个进度条的宽度为 50,显示不同的 Unicode 字符:

<p align="center"> <img src="https://yellow-cdn.veclightyear.com/2b54e442/07421f9e-08ee-47a3-8690-6d7086b606c8.gif"/> </p>
#include <chrono> #include <indicators/progress_bar.hpp> #include <indicators/indeterminate_progress_bar.hpp> #include <indicators/cursor_control.hpp> #include <thread> int main() { indicators::show_console_cursor(false); std::this_thread::sleep_for(std::chrono::milliseconds(2000)); { // 普通 ASCII indicators::ProgressBar bar{ indicators::option::BarWidth{50}, indicators::option::Start{"["}, indicators::option::Fill{"="}, indicators::option::Lead{">"}, indicators::option::Remainder{" "}, indicators::option::End{" ]"}, indicators::option::PostfixText{"普通 ASCII"}, indicators::option::ForegroundColor{indicators::Color::green}, indicators::option::FontStyles{ std::vector<indicators::FontStyle>{indicators::FontStyle::bold}} }; // 更新进度条状态 while (true) { bar.tick(); if (bar.is_completed()) break; std::this_thread::sleep_for(std::chrono::milliseconds(10)); } } { // Unicode indicators::ProgressBar bar{ indicators::option::BarWidth{50}, indicators::option::Start{"["}, indicators::option::Fill{"驚くばかり"}, indicators::option::Lead{">"}, indicators::option::Remainder{" "}, indicators::option::End{" ]"}, indicators::option::PostfixText{"日语"}, indicators::option::ForegroundColor{indicators::Color::yellow}, indicators::option::FontStyles{ std::vector<indicators::FontStyle>{indicators::FontStyle::bold}} }; // 更新进度条状态 while (true) { bar.tick(); if (bar.is_completed()) break; std::this_thread::sleep_for(std::chrono::milliseconds(10)); } } { // 俄语 indicators::ProgressBar bar{ indicators::option::BarWidth{50}, indicators::option::Start{"["}, indicators::option::Fill{"Потрясающие"}, indicators::option::Remainder{" "}, indicators::option::End{" ]"}, indicators::option::PostfixText{"俄语"}, indicators::option::ForegroundColor{indicators::Color::red}, indicators::option::FontStyles{ std::vector<indicators::FontStyle>{indicators::FontStyle::bold}} }; // 更新进度条状态 while (true) { bar.tick(); if (bar.is_completed()) break; std::this_thread::sleep_for(std::chrono::milliseconds(10)); } } { // 希腊语 indicators::ProgressBar bar{ indicators::option::BarWidth{50}, indicators::option::Start{"["}, indicators::option::Fill{"Φοβερός"}, indicators::option::Remainder{" "}, indicators::option::End{" ]"}, indicators::option::PostfixText{"希腊语"}, indicators::option::ForegroundColor{indicators::Color::cyan}, indicators::option::FontStyles{ std::vector<indicators::FontStyle>{indicators::FontStyle::bold}} }; // 更新进度条状态 while (true) { bar.tick(); if (bar.is_completed()) break; std::this_thread::sleep_for(std::chrono::milliseconds(10)); } } { // 中文 indicators::ProgressBar bar{ indicators::option::BarWidth{50}, indicators::option::Start{"["}, indicators::option::Fill{"太棒了"}, indicators::option::Remainder{" "}, indicators::option::End{" ]"}, indicators::option::PostfixText{"中文"}, indicators::option::ForegroundColor{indicators::Color::green}, indicators::option::FontStyles{ std::vector<indicators::FontStyle>{indicators::FontStyle::bold}} }; // 更新进度条状态 while (true) { bar.tick(); if (bar.is_completed()) break; std::this_thread::sleep_for(std::chrono::milliseconds(10)); } } { // 表情符号 indicators::ProgressBar bar{ indicators::option::BarWidth{50}, indicators::option::Start{"["}, indicators::option::Fill{"🔥"}, indicators::option::Lead{"🔥"}, indicators::option::Remainder{" "}, indicators::option::End{" ]"}, indicators::option::PostfixText{"表情符号"}, indicators::option::ForegroundColor{indicators::Color::white}, indicators::option::FontStyles{ std::vector<indicators::FontStyle>{indicators::FontStyle::bold}} }; // 更新进度条状态 while (true) { bar.tick(); if (bar.is_completed()) break; std::this_thread::sleep_for(std::chrono::milliseconds(10)); } } { // 不确定进度条 indicators::IndeterminateProgressBar bar{ indicators::option::BarWidth{50}, indicators::option::Start{"["}, indicators::option::Fill{"✯"}, indicators::option::Lead{"載入中"}, indicators::option::End{" ]"}, indicators::option::PostfixText{"加载进度条"}, indicators::option::ForegroundColor{indicators::Color::yellow}, indicators::option::FontStyles{ std::vector<indicators::FontStyle>{indicators::FontStyle::bold}} }; auto job = [&bar]() { std::this_thread::sleep_for(std::chrono::milliseconds(10000)); bar.mark_as_completed(); }; std::thread job_completion_thread(job); // 更新进度条状态 while (!bar.is_completed()) { bar.tick(); std::this_thread::sleep_for(std::chrono::milliseconds(100)); } job_completion_thread.join(); } indicators::show_console_cursor(true); return 0; }

构建示例

git clone https://github.com/p-ranav/indicators cd indicators mkdir build && cd build cmake -DINDICATORS_SAMPLES=ON -DINDICATORS_DEMO=ON .. make

WinLibs + MinGW

对于 Windows,如果你像我一样使用 WinLibs,cmake 命令会像这样:

foo@bar:~$ mkdir build && cd build foo@bar:~$ cmake -G "MinGW Makefiles" -DCMAKE_CXX_COMPILER="C:/WinLibs/mingw64/bin/g++.exe" -DINDICATORS_SAMPLES=ON -DINDICATORS_DEMO=ON .. foo@bar:~$ make -j4

生成单头文件

python3 utils/amalgamate/amalgamate.py -c single_include.json -s .

贡献

欢迎贡献,请查看 CONTRIBUTING.md 文档以获取更多信息。

许可

该项目使用 MIT 许可证。

编辑推荐精选

讯飞星火

讯飞星火

深度推理能力全新升级,全面对标OpenAI o1

科大讯飞的星火大模型,支持语言理解、知识问答和文本创作等多功能,适用于多种文件和业务场景,提升办公和日常生活的效率。讯飞星火是一个提供丰富智能服务的平台,涵盖科技资讯、图像创作、写作辅助、编程解答、科研文献解读等功能,能为不同需求的用户提供便捷高效的帮助,助力用户轻松获取信息、解决问题,满足多样化使用场景。

模型训练热门AI工具内容创作智能问答AI开发讯飞星火大模型多语种支持智慧生活
Spark-TTS

Spark-TTS

一种基于大语言模型的高效单流解耦语音令牌文本到语音合成模型

Spark-TTS 是一个基于 PyTorch 的开源文本到语音合成项目,由多个知名机构联合参与。该项目提供了高效的 LLM(大语言模型)驱动的语音合成方案,支持语音克隆和语音创建功能,可通过命令行界面(CLI)和 Web UI 两种方式使用。用户可以根据需求调整语音的性别、音高、速度等参数,生成高质量的语音。该项目适用于多种场景,如有声读物制作、智能语音助手开发等。

Trae

Trae

字节跳动发布的AI编程神器IDE

Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。

热门AI工具生产力协作转型TraeAI IDE
咔片PPT

咔片PPT

AI助力,做PPT更简单!

咔片是一款轻量化在线演示设计工具,借助 AI 技术,实现从内容生成到智能设计的一站式 PPT 制作服务。支持多种文档格式导入生成 PPT,提供海量模板、智能美化、素材替换等功能,适用于销售、教师、学生等各类人群,能高效制作出高品质 PPT,满足不同场景演示需求。

讯飞绘文

讯飞绘文

选题、配图、成文,一站式创作,让内容运营更高效

讯飞绘文,一个AI集成平台,支持写作、选题、配图、排版和发布。高效生成适用于各类媒体的定制内容,加速品牌传播,提升内容营销效果。

AI助手热门AI工具AI创作AI辅助写作讯飞绘文内容运营个性化文章多平台分发
材料星

材料星

专业的AI公文写作平台,公文写作神器

AI 材料星,专业的 AI 公文写作辅助平台,为体制内工作人员提供高效的公文写作解决方案。拥有海量公文文库、9 大核心 AI 功能,支持 30 + 文稿类型生成,助力快速完成领导讲话、工作总结、述职报告等材料,提升办公效率,是体制打工人的得力写作神器。

openai-agents-python

openai-agents-python

OpenAI Agents SDK,助力开发者便捷使用 OpenAI 相关功能。

openai-agents-python 是 OpenAI 推出的一款强大 Python SDK,它为开发者提供了与 OpenAI 模型交互的高效工具,支持工具调用、结果处理、追踪等功能,涵盖多种应用场景,如研究助手、财务研究等,能显著提升开发效率,让开发者更轻松地利用 OpenAI 的技术优势。

Hunyuan3D-2

Hunyuan3D-2

高分辨率纹理 3D 资产生成

Hunyuan3D-2 是腾讯开发的用于 3D 资产生成的强大工具,支持从文本描述、单张图片或多视角图片生成 3D 模型,具备快速形状生成能力,可生成带纹理的高质量 3D 模型,适用于多个领域,为 3D 创作提供了高效解决方案。

3FS

3FS

一个具备存储、管理和客户端操作等多种功能的分布式文件系统相关项目。

3FS 是一个功能强大的分布式文件系统项目,涵盖了存储引擎、元数据管理、客户端工具等多个模块。它支持多种文件操作,如创建文件和目录、设置布局等,同时具备高效的事件循环、节点选择和协程池管理等特性。适用于需要大规模数据存储和管理的场景,能够提高系统的性能和可靠性,是分布式存储领域的优质解决方案。

TRELLIS

TRELLIS

用于可扩展和多功能 3D 生成的结构化 3D 潜在表示

TRELLIS 是一个专注于 3D 生成的项目,它利用结构化 3D 潜在表示技术,实现了可扩展且多功能的 3D 生成。项目提供了多种 3D 生成的方法和工具,包括文本到 3D、图像到 3D 等,并且支持多种输出格式,如 3D 高斯、辐射场和网格等。通过 TRELLIS,用户可以根据文本描述或图像输入快速生成高质量的 3D 资产,适用于游戏开发、动画制作、虚拟现实等多个领域。

下拉加载更多