CBlueUI  
C++ 跨平台跨框架的数据可视化工具
载入中...
搜索中...
未找到
安装和工具

§. 下载 / Download

  1. 解压文件即可:包含头文件、动态链接库,cmake文件,demo文件,自动化脚本
  2. 产品采用C++11标准。若您的需求是C98标准。请联系我们定制发布。
  3. 专业VLD内存泄漏检测工具。验证无内存泄漏。

§. 开始第一个APP创建

  • 第一种方式:手动创建空项目:
    • 将CBlueUI.h头文件,所在目录添加到包含目录中
    • 将CBlueUI.lib文件,所在目录添加到链接目录中
    • 将CBlueUI.dll文件,拷贝到和APP同级目录下。或者添加到系统环境变量。任选一个即可
  • 第二种方式:使用CMake工具导入该库
    • CMake是简单易学的工程构建工具。可自动生成各类开发工具的工程文件。请自行前往CMake官网下载.
    • 您也可以直接链接,集成到成熟的产品项目中
      list(APPEND CMAKE_PREFIX_PATH "library_dir") # 替换library_dir为库解压目录
      find_package(CBlueUI) # 添加依赖关系
      target_link_libraries(${target} CBlueUI) # target 为输出目标
    • 发布的产品包含demo源码。可直接用cmake构建
      注意:切换工程到release模式,否则运行会异常。
      C++标准发展时间简史。
      C++98和C++11:是使用最广的标准。版本越低兼容性越好。版本越高,代码可塑能力越强,更灵活。在底层嵌入式开发中有些编译器未必支持最新的标准。在实际开发中标准的选择,能为后期迁移代码平台减少不必要的麻烦

§. 快速了解CBlueUI

这里挑出来一些常用的类。想看详细类介绍。请在搜索框中直接检索类名

系统初始化

  • UISystemStartUp结构体 在主函数入口(main)中初始化。结构包含类控件生命周期,各种资源管理的对象。 程序退出时自动释放所有资源。下图例子完整源码。已和产品一并发布。
    void main()
    {
    UISystemStartUp uistartup;
    InitializeUISystem(&uistartup);
    // 安装全局消息提示框
    CToastBox toastBox;
    InstallToastBox(&toastBox);
    // 加载资源
    const char* res_file = "../res/image_def.xml";
    XmlBuilder::ApplyResourceWithFile(res_file);
    }

XML和JSON格式解析

  • XmlStorage类 分为 XmlStorageA 和 XmlStorageW 版本
    • 从内存缓冲区解析
      // brief 加载xml格式数据
      // param xmlText 数据
      // param len 数据长度
      // param no_write TRUE代表xmlText是不可写字符串,解析常量字符串时,需要标记为TRUE
      int LoadBuffer(const char* xmlText, int len = -1, BOOL no_write = FALSE);
      // brief 加载json数据并转换为xml树结构
      // param jsonText 数据
      // param len 数据长度
      // param to_xml: TRUE表示将json格式转换为紧凑的XML格式。FALSE表示保持json的树结构
      int LoadBufferJson(const char* jsonText, int len = -1, BOOL to_xml = FALSE);
    • 例子
      // 传入xml文件或者json文件。通过后缀自动识别
      XmlStorageA templateUI("../res/image_def.xml");
      const XMLItemA* pRoot = templateUI.Root()->firstChild;
      while (pRoot)
      {
      pRoot = pRoot->nextSibling;
      }

时间工具

  • CTimeElapsed类 用于计算任务的时间性能。单位毫秒
    CTimeElapsed spand;
    spand.Start();
    // run task...
    double cost_time = spand.GetElapsedMicroseconds();
  • CTimerTask类 定时器任务
    CTimerTask m_anim_timer; // 定时器对象。对象析构时自动释放。无需手动清楚
    m_anim_timer.KillTimer(); // 主动移除定时器任务
    auto func_anim = [this]() {
    // run task...
    };
    m_anim_timer.SetTimer(func_anim, ms, 100, 0); // 可以传入静态函数或者lamda表达式
  • time_stamp结构体 时间戳
    bool is_utc = false; // false 代表本地时区时间,true 代表国际标准时间
    int timezone = 0; // 最终时间结果会加上这个定义的时差
    // get_current_time_stamp(&tm2, false, 8); ///< 结果为当地时间+8小时时差后的时间
    // get_current_time_stamp(&tm2, true, 8); ///< 结果为UTC标准时间+8小时时差后的时间
    get_current_time_stamp(&tm2, is_utc, timezone);
    time.format(_Txt("[%d-%02d-%02d %d:%d:%d.%06ld]"), tm2.tm_year, tm2.tm_mon, tm2.tm_mday, tm2.tm_hour, tm2.tm_min, tm2.tm_sec, tm2.tm_usec);

文件IO和日志

  • UtilsFileSystem 命名空间。
    // 判断文件是否存在
    BOOL IsExistsA(LPCSTR folder);
    BOOL IsExistsW(LPCWSTR folder);
    // 创建目录
    BOOL MakeDirA(LPCSTR folder);
    BOOL MakeDirW(LPCSTR folder);
  • FileReader类 读取文件
    FileReader resfile;
    #ifdef _WIN32
    // 读取WIN32资源
    resfile.LoadImageFromResource(::GetModuleHandle(NULL), _Txt("IDR_XML_IMAGEDEF"), _Txt("XML"));
    #endif
    TCHAR* full_path = _Txt(""); ///< 文件路径
    resfile.LoadFile(full_path); ///< 读取文件
    DataBuffer dbffer = resfile.GetDataBuffer(TRUE); // 获得文件数据
  • FileWriter类 写入文件
    FileWriter writer;
    TCHAR* file_name_utf8 = _Txt(""); ///< 文件路径,若目录不存在,则无法写入
    TCHAR* mode = _Txt("w");
    // 打开文件
    writer.OpenFile(const TCHAR* filename, const TCHAR* mode);
    // 写入内容
    writer.PrintfChar("hello china. %d", 365);
    // 关闭文件
    writer.Close();
  • LoggerStorage类 日志管理
    // 一般设置为全局对象,对整个APP。进行日志记录
    LoggerStorage log_file;
    log_file.InitFileLogger("./log/log_test.html");
    for (size_t i = 0; i < 200000; i++)
    {
    log_file.PrintLogA(LogLevel::LogLevel_TRACE, TRUE, __FILE__, __LINE__, "test.....");
    log_file.PrintLogA(LogLevel::LogLevel_DEBUG, TRUE, __FILE__, __LINE__, "test.....");
    log_file.PrintLogA(LogLevel::LogLevel_INFO, TRUE, __FILE__, __LINE__, "test.....");
    log_file.PrintLogA(LogLevel::LogLevel_WARN, TRUE, __FILE__, __LINE__, "test.....");
    log_file.PrintLogA(LogLevel::LogLevel_ERROR, FALSE, __FILE__, __LINE__, "test.....");
    log_file.PrintLogA(LogLevel::LogLevel_FATAL, FALSE, __FILE__, __LINE__, "test.....");
    log_file.LoggerFlush();
    }

数值和字符操作

  • BeStringA类 UTF8格式字符串。详情请参考类文档
  • BeStringW类 UTF16格式的unicode字符串。常用字符基本为两个字节(一个宽字符)。这很重要。在遍历宽字符时,应该判断字符字节长度。而不是简单的自增(+1)。这个做实验也很简单。感兴趣的可以动手验证。 详情请参考类文档
  • BasicStringBufferA类 固定缓冲区字符操作类。当字符超过固定大小时,才分配内存 优点:在栈空间处理短字符串。避免频繁操作形成堆内存碎片
  • BasicStringBufferW类 同上
    char tempdata[1024];
    BasicStringBufferA szbuf(tempdata, 1024);
    szbuf.init("hello-"); // 初始化赋值
    szbuf.append("china"); // 追加字符
    // 最后输出为: hello-china
  • 字符转换 UtilsString UtilsString为命名空间。并非类名。详情请参考类文档
    • 多字符集之间转换 相同的符号在不同的字符集中,对应的码点(codepoint)不一样。这里变换后会改变码点。编码方式不变。
      #ifdef WIN32
      return _access(folder, 0) != -1;
      // CP_UTF8:表示folder的编码方式
      // CP_ACP:表示ansistr输出参数的编码方式
      UtilsString::ToMultiByte(folder, -1, ansistr, CP_UTF8, CP_ACP);
      #endif
    • 宽字符转换为多字节字符
      UINT to_codepage = UI_DEFAULT_CODEPAGE;
      // Unicode --> 多字符集。to_codepage为目标字符串的字符集(早期并没有unicode,各地区都有自己的本地码点标准。比如中国有自己的国标),一版为utf8或本地字符集
      UtilsString::UnicodeToMultiByte(filename, -1, path_str, to_codepage);
    • 多字节字符转换为宽字符
      // CP_UTF8表示msg的编码方式
    • 字符串分词拆分。通过单个字符匹配
      /**
      * @brief 字符串分词拆分。单个字符匹配
      *
      * @param str 输入字符串
      * @param pattern 分割字符集合
      * @param count 匹配次数
      * @param skip_bracket TRUE:忽略被{'(', ')'}, {'[', ']'}, {'{', '}'}, {'<', '>'}包裹的匹配字符
      * @return std::vector<std::string> 分词结果
      */
      std::vector<std::string> SplitWithCharA(const char* str, const char* pattern, int count = 0, BOOL skip_bracket = FALSE);
      std::vector<std::w16string> SplitWithCharW(const WCHAR* str, const WCHAR* pattern, int count = 0, BOOL skip_bracket = FALSE);
      // 例子
      std::vector<std::string> suffixlist = UtilsString::SplitWithCharA("1-;2-;3-;4-", ";", -1);
      // 输出结果为:suffixlist=[1-,2-,3-,4-];
      std::vector<std::string> suffixlist2 = UtilsString::SplitWithCharA("1-a;2-b;3-b;4-d", ";-", -1);
      // 输出结果为:suffixlist2=[1,a,2,b,3,b,4,d]; 这种属于同时匹配多个字符。这里是';' 和 '-'两个分割字符
    • 字符串分词拆分。通过字符串匹配
      /**
      * @brief 字符串分词拆分。字符串匹配
      *
      * @param str 输入字符串
      * @param pattern 分割字符串
      * @param count 匹配次数
      * @param skip_bracket TRUE:忽略被{'(', ')'}, {'[', ']'}, {'{', '}'}, {'<', '>'}包裹的匹配字符串
      * @return std::vector<std::string> 分词结果
      */
      UI_EXP std::vector<std::string> SplitWithTextA(std::string str, std::string pattern, int count = 0);
      UI_EXP std::vector<std::w16string> SplitWithTextW(std::w16string str, std::w16string pattern, int count = 0);
      // 例子
      std::vector<std::string> suffixlist = UtilsString::SplitWithTextA("1-;2-;3-;4-", "-;", -1);
      // 输出结果为:suffixlist=[1,2,3,4-]; 此时"-;"是作为完整的字串进行匹配。必须保证连续

2D、3D变换矩阵

  • Transform2d类 二维变换矩阵。平移,缩放,斜切。
    Transform2d img_mtx;
    int cx = 100;
    int cy = 100;
    double scale_x = 2.0;
    double scale_y = 2.0;
    img_mtx *= Transform2dTranslation(-cx, -cy); ///<先平移至缩放中心点
    img_mtx *= Transform2dScaling(scale_x, scale_y); ///< 缩放变换
    img_mtx *= Transform2dRotation(angle); ///<旋转变换
    img_mtx *= Transform2dTranslation(cx, cy); ///< 再平移恢复原来中心点
    double x0 = 10, y0 = 10;
    img_mtx.transform(&x0, &y0); // 对(x0,y0)进行变换并且输出
  • MatFloat4x4类 三维变换矩阵。平移,缩放,斜切。
    float ratio = 16.0 / 9.0;
    MatFloat4x4 Mcamera = MatFloat4x4::Lookat(VecFloat3(0, 0, 1), // Camera is at (0,0,1), in World Space 相机位置
    VecFloat3(0, 0, -1), // and looks at the origin 观察点坐标
    VecFloat3(0, -1, 0) // Head is up (set to 0,-1,0 to look upside-down) 相机 up 方向,即相机头部朝向
    );
    MatFloat4x4 Mproj = MatFloat4x4::Ortho(-ratio, ratio, -1.0f, 1.0f, 0.1f, 100.0f);
    MatFloat4x4 Mmodel;
    Mmodel *= MatFloat4x4::RotateX(m_rotate_xyz.f[0]);
    Mmodel *= MatFloat4x4::RotateY(m_rotate_xyz.f[1]);
    Mmodel *= MatFloat4x4::RotateZ(m_rotate_xyz.f[2]);
    MatFloat4x4 Mscreen;
    Mscreen.r[0].f[0] = width / 2;
    Mscreen.r[1].f[1] = height / 2;
    Mscreen.r[0].f[3] = (width - 1) / 2 + rcDiagram.left;
    Mscreen.r[1].f[3] = (height - 1) / 2 + rcDiagram.top;
    MatFloat4x4 Mu = Mscreen * Mproj * Mcamera * Mmodel;
    VecFloat4 point_zero(0, 0, 0, 1);
    Mu.Transform(point_zero); ///< 对point_zero进行3D变换

渲染引擎

  • 软渲染 在AGG2.4的基础上新增3D算法。优化内存。魔改之后的版本功能更全。 产品发布包含了第三方绘图引擎的协议许可。
  • OpenGL渲染 在NanoVG的基础上新增3D算法。纹理的切线贴图。高斯模糊,放大镜特效,阴影特效。
  • DirectX渲染 仅Window平台可用。DirectX在window平台上表现同样丝滑。
  • ISurface 绘图接口 包含基本绘制图元的函数。请检索查阅详情。
    // 例子。更多接口请查阅类文档
    virtual void FillRect(RECT rc, const GColor& color);
    virtual void FillRoundRect(RECT rc, RoundRectRadius& radius, const GColor& color);
  • GImage 位图对象
    // 从数据流读取并解码图像到位图
    bool LoadBufferImage(unsigned char* buffer, UINT dwSize);
    // 若需要读取图像文件,可先使用FileReader读取到数据缓冲区
  • GColor 颜色对象
    public:
    UINT8 r;
    UINT8 g;
    UINT8 b;
    UINT8 a; // 0:全透明,255不透明
  • GPathStorage 几何路径对象
    void PathMoveTo(double x, double y);
    void PathLineTo(double x, double y);
    void PathHLineTo(double x);
    void PathVLineTo(double y);
    void PathArcTo(double x, double y, double rx, double ry, double a1, double a2, bool ccw = true);
    void PathJoinArcTo(double x, double y, double rx, double ry, double a1, double a2, bool ccw);
    void PathPie(double x0, double y0, double rx, double ry, double a1, double a2); // 饼图路径
    void PathRing(double x0, double y0, double rx, double ry, double a1, double a2, double dis); // 环状路径
    void PathRingRound(double x0, double y0, double rx, double ry, double a1, double a2, double dis, double round = PI / 45);
    void PathEllipse(int cx, int cy, int rx, int ry);
    // 更多API请参考类文档

界面构解析器

  • XmlBuilder类 控件和资源解析器
    注意:若UI文件中使用了全局资源。应该先加载资源。
    • 全局资源加载
      // 资源文件。请参考资源文件语法格式
      const char* res_file = "../res/image_def.xml";
      //静态成员函数。
      XmlBuilder::ApplyResourceWithFile(res_file);
    • 控件解析
      // UI文件。请参考UI文件语法格式
      const char* main_xml_file = "../res/00_uidemo.xml";
      // UI管理对象。负责绘制,消息转发
      UIManager m_manger;
      // 这里C00_uidemoHandler是代码助手自动生成对象。(代码助手如何用,后面介绍)
      // 用户处理逻辑业务的类。
      C00_uidemoHandler mainHandler(&m_manger);
      XmlBuilder parse; // 解析对象
      parse.LoadUIFileA(main_xml_file, &m_manger, NULL, NULL, &mainHandler);

代码助手使用

  • python环境。使用前请安装python
    #检查是否安装python
    python --version
  • 启动命令行

    #显示帮助信息
    python3 generate_code_cpp.py -h
    #代码生成
    # --input 后面可以跟多个文件和文件夹
    python3 generate_code_cpp.py --input "E:/CBlueUI/res/00_uidemo.xml" --output "E:/CBlueUI/res/code"

  • 完成后,会生成C++源代码。将源代码添加到工程项目中参与编译即可。

设计器

  • 可以提前预览UI布局。节约设计时间。
  • 在线预览器:CBlueUIDesigner.html
  • 在多人开发中。可以独立分工。不依赖于项目的编译运行。
鄂公网安备42018502007752 鄂ICP备2024082886
Copyright © 2025 · CBlueStudio 版权所有