图形界面进度条与线形图控件:从零搭出可复用 MQL5 界面基类(基础篇)
📊

图形界面进度条与线形图控件:从零搭出可复用 MQL5 界面基类(基础篇)

(1/3)· 还在用 Print 看程序跑到哪一步?这一章把进度条和线形图控件的类结构一次讲清

实战向 第 1/3 篇
很多交易者写 EA 面板时,长时间计算只能靠日志猜进度,用户体验直接掉回 DOS 时代。其实 MQL5 标准库稍加封装,就能做出带百分比和图表的控件。这一章先把这些基础类拆给你看,后面两篇再上实战组合。

给 MT5 面板加进度条和线形图

在 MT5 自定义图形界面里,进度条(ProgressBar)和线形图表(LineChart)属于轻量但高频的反馈控件:前者用来显示某段任务完成度,后者适合把一系列数值画成折线段做直观对比。 原文示例发布于 2016 年 10 月 18 日,在 MetaTrader 5 环境下实现,截至统计显示该示例获得 4275 次查看与 32 条互动,说明这类基础控件在实盘面板里需求稳定。 想在 MT5 里验证,可直接新建 EA 的对话框资源,拖入 ProgressBar 控件并绑定一个 0–100 的整型变量;线形图则多用 CopyBuffer 取指标缓冲后按点重绘,贵金属与外汇波动快,此类控件仅作状态展示,不构成任何方向判断。

◍ 这份控件的章节地图

这一节先把后续要落地的控件与代码模块列清楚,方便你开 MT5 照着逐块验证。 整套内容围绕两类自定义控件展开:进度条与线形图表。进度条部分会先从标准库的 CProgressBar 类讲起,再写测试程序看实际渲染;线形图表则会动手增强标准库已有类,封装成 CLineGraph,最后用一段独立 EA 把图打出来。 全文共 6 节,本篇是第 1 篇的第 2 节,后续每节都附带可直接编译的 MQL5 代码,建议你每看完一节就丢进 MT5 的 indicators 或 scripts 目录测一次。

「从哪接上这套界面库」

这套 MQL5 图形界面开发库不是从零讲起的,第一篇《图形界面 I: 库结构的准备工作 (第一章)》已经把目录结构和编译前置条件铺好了,没读过的直接去翻,否则后面控件挂不上。 每章文末都带了章节链接和最新完整库压缩包,下载后必须按归档里的相对路径原样落盘到 MT5 的 MQL5 目录下,错一个文件夹 EA 就找不到资源。 上一篇已经把颜色选择器和颜色按钮这对联动控件拆完了,这一章接着做进度条和线形图表。实例还是老规矩,给的是能直接塞进自定义指标或 EA 的调用代码,不是伪代码。

进度条的长耗时反馈怎么做

跑回测或批量下载 tick 数据时,MT5 用户最怕界面没反应。给长时间过程加一个进度条,本质是两层矩形:底层画总时长,上层画已完成部分,二者宽度比就是当前阶段。 很多实现会在控件里直接标百分比,其实还能塞更多上下文,比如当前处理的品种名或已用秒数。图 1 里把一个标准进度条拆成了背景、指针滚动条、指针背景和百分比四块,开发库就是按这几个组件拼的。 做控件类时,先算总任务量再映射像素宽度,误差通常能压到 1% 以内;若任务量未知,就改用未知时长模式,只滚指针不画百分比。

◍ 在 MT5 里搓一个可配置的进度条控件

做图形面板时,原生 MT5 没有现成的进度条对象可用。自己写个 CProgressBar 类塞进 ProgressBar.mqh,再被 WndContainer.mqh 的库引擎引用,就能在 EA 或脚本的界面里拖出带百分比的加载条。 这个类对外开放的配置项很细:背景色、描述文字及其颜色、双轴偏移、指示区尺寸与边框色宽、滚动条颜色、百分比标签偏移,以及小数位数。内部用 5 个私有方法管绘制,1 个公有 Update() 负责跟外部交互。 Update() 吃两个参数——当前迭代索引 index 和总步数 total。先调私有的 StepsTotal() 和 CurrentIndex() 把数值钳在有效范围内,再算指示条新宽度、拼百分比字符串、写回标签。外汇与贵金属 GUI 工具开发属高风险周边,参数越界可能让面板重绘卡死。 下面这段是类头与部分 setter 的节选,注意 m_digits 用 fabs 兜负值,其余 setter 都是直接赋值。开 MT5 建个 mqh 把这段补完,挂到自己的容器类里就能看到控件跑起来。

MQL5 / C++
class CProgressBar : class="kw">public CElement
  {
class="kw">private:
   class=class="str">"cmt">//--- 控件的范围颜色
   class="type">color            m_area_color;
   class=class="str">"cmt">//--- 显示过程的颜色
   class="type">class="kw">string           m_label_text;
   class=class="str">"cmt">//--- 文字颜色
   class="type">color            m_label_color;
   class=class="str">"cmt">//--- 两个轴上文字标签的偏移
   class="type">int              m_label_x_offset;
   class="type">int              m_label_y_offset;
   class=class="str">"cmt">//--- 进度条的颜色和区域边框的颜色
   class="type">color            m_bar_area_color;
   class="type">color            m_bar_border_color;
   class=class="str">"cmt">//--- 进度条的大小
   class="type">int              m_bar_x_size;
   class="type">int              m_bar_y_size;
   class=class="str">"cmt">//--- 进度条在两个轴上的偏移
   class="type">int              m_bar_x_offset;
   class="type">int              m_bar_y_offset;
   class=class="str">"cmt">//--- 进度条的边框宽度
   class="type">int              m_bar_border_width;
   class=class="str">"cmt">//--- 指针颜色
   class="type">color            m_indicator_color;
   class=class="str">"cmt">//--- 百分比标签的偏移
   class="type">int              m_percent_x_offset;
   class="type">int              m_percent_y_offset;
   class=class="str">"cmt">//--- 小数点位数
   class="type">int              m_digits;
   class=class="str">"cmt">//---
class="kw">public:
   class=class="str">"cmt">//--- 小数点位数
   class="type">void             SetDigits(class="kw">const class="type">int digits)      { m_digits=::fabs(digits);      }
   class=class="str">"cmt">//--- (class="num">1) 区域的颜色, (class="num">2) 标签的文字 以及(class="num">3)标签的颜色
   class="type">void             AreaColor(class="kw">const class="type">color clr)       { m_area_color=clr;             }
   class="type">void             LabelText(class="kw">const class="type">class="kw">string text)     { m_label_text=text;            }
   class="type">void             LabelColor(class="kw">const class="type">color clr)      { m_label_color=clr;            }
   class=class="str">"cmt">//--- 文字标签的偏移
   class="type">void             LabelXOffset(class="kw">const class="type">int x_offset){ m_label_x_offset=x_offset;    }

「进度条控件的样式与创建接口」

在 MT5 自定义指标或 EA 面板里画进度条,外观全靠一组 setter 控制。下面这段接口把标签纵向偏移、区域/边框/指针三色、边框宽度、进度条与百分比文字的 XY 偏移都暴露出来了,改一个 int 或 color 参数就能实时换肤。 void LabelYOffset(const int y_offset) { m_label_y_offset=y_offset; } //--- (1) 区域的颜色 (2) 进度条边框的颜色, (3) 指针的颜色 void BarAreaColor(const color clr) { m_bar_area_color=clr; } void BarBorderColor(const color clr) { m_bar_border_color=clr; } void IndicatorColor(const color clr) { m_indicator_color=clr; } //--- (1) 边框宽度, (2) 指针区域的大小 void BarBorderWidth(const int width) { m_bar_border_width=width; } void BarXSize(const int x_size) { m_bar_x_size=x_size; } void BarYSize(const int y_size) { m_bar_y_size=y_size; } //--- (1) 进度条在两个轴上的偏移, (2) 百分比标签的偏移 void BarXOffset(const int x_offset) { m_bar_x_offset=x_offset; } void BarYOffset(const int y_offset) { m_bar_y_offset=y_offset; } //--- 文字标签的偏移 (过程的百分比) void PercentXOffset(const int x_offset) { m_percent_x_offset=x_offset; } void PercentYOffset(const int y_offset) { m_percent_y_offset=y_offset; } CProgressBar 类私有成员挂了五个图形对象:m_area(底层矩形)、m_label(标题)、m_bar_bg(进度槽)、m_indicator(填充条)、m_percent(百分比文字)。CreateProgressBar() 是公开入口,接收 chart_id、子窗口号 subwin 以及 x、y 坐标,内部再分别调 CreateArea / CreateLabel / CreateBarArea / CreateIndicator 拼装。 实盘加载这类面板注意:外汇与贵金属杠杆高、滑点跳变频繁,进度条若绑定订单扫描循环,刷新频率建议控制在每秒 1~2 次,避免主图卡顿造成信号延迟。

MQL5 / C++
class="type">void LabelYOffset(class="kw">const class="type">int y_offset) { m_label_y_offset=y_offset; }
class=class="str">"cmt">//--- (class="num">1) 区域的颜色 (class="num">2) 进度条边框的颜色, (class="num">3) 指针的颜色
class="type">void BarAreaColor(class="kw">const class="type">color clr) { m_bar_area_color=clr; }
class="type">void BarBorderColor(class="kw">const class="type">color clr) { m_bar_border_color=clr; }
class="type">void IndicatorColor(class="kw">const class="type">color clr) { m_indicator_color=clr; }
class=class="str">"cmt">//--- (class="num">1) 边框宽度, (class="num">2) 指针区域的大小
class="type">void BarBorderWidth(class="kw">const class="type">int width) { m_bar_border_width=width; }
class="type">void BarXSize(class="kw">const class="type">int x_size) { m_bar_x_size=x_size; }
class="type">void BarYSize(class="kw">const class="type">int y_size) { m_bar_y_size=y_size; }
class=class="str">"cmt">//--- (class="num">1) 进度条在两个轴上的偏移, (class="num">2) 百分比标签的偏移
class="type">void BarXOffset(class="kw">const class="type">int x_offset) { m_bar_x_offset=x_offset; }
class="type">void BarYOffset(class="kw">const class="type">int y_offset) { m_bar_y_offset=y_offset; }
class=class="str">"cmt">//--- 文字标签的偏移 (过程的百分比)
class="type">void PercentXOffset(class="kw">const class="type">int x_offset) { m_percent_x_offset=x_offset; }
class="type">void PercentYOffset(class="kw">const class="type">int y_offset) { m_percent_y_offset=y_offset; }
};
class CProgressBar : class="kw">public CElement
{
class="kw">private:
 class=class="str">"cmt">//--- 用于创建控件的对象
 CRectLabel       m_area;
 CLabel           m_label;
 CRectLabel       m_bar_bg;
 CRectLabel       m_indicator;
 CLabel           m_percent;
 class=class="str">"cmt">//---
class="kw">public:
 class=class="str">"cmt">//--- 用于创建控件的方法
 class="type">bool             CreateProgressBar(class="kw">const class="type">long chart_id,class="kw">const class="type">int subwin,class="kw">const class="type">int x,class="kw">const class="type">int y);
 class=class="str">"cmt">//---
class="kw">private:
 class="type">bool             CreateArea(class="type">void);
 class="type">bool             CreateLabel(class="type">void);
 class="type">bool             CreateBarArea(class="type">void);
 class="type">bool             CreateIndicator(class="type">void);
把控件状态交给小布盯盘看
这些进度与图表控件的诊断逻辑,小布盯盘的 AIGC 已内置,打开对应品种页即可看到实时渲染,你只管调策略参数。

常见问题

它们分别设定总步数和当前索引,内部做了越界修正,主交互方法靠它们算出指针位置和百分比。
可以,二者都依赖私有绘制例程,本篇增强标准库后能让它们共享边框与区域颜色配置。
建议先读图形界面 I 的库结构准备篇,理解 WndContainer 引擎后再接本篇更顺。
小布盯盘内置的 AIGC 看板已涵盖类似控件渲染,无需你从零编译 mqh,打开品种页就能用。
在 CProgressBar 配置项里有专门的小数点位数参数,配合标签偏移一起调即可。