量化软件:在赫兹量化中基于 CChartObject 类设计和实施新 GUI 组件
过快速浏览,我们可以得出基于其他类编写新的图形对象类时适用的基本规则:
更改对象创建的 Create() 方法
更改返回对象类型的 Type() 方法
添加属性访问修饰符
不是所有的规则都必须应用,可以只添加新的访问修饰符或在类中添加新的变量和/或对象。
在我们继续前,我来介绍一下如何在图形对象上使用 CChartObject 方法。
使用对象属性而非 ObjectSet 和 ObjectGet 方法系列足以声明 CChartObject 或后代对象以及调用更改其所需属性的方法。为使其更加简单,我提供了一个普通标签的示例。
我们无需编写:
void OnStart() { //--- string label_name="my_OBJ_LABEL_object"; if(ObjectFind(0,label_name)<0) { Print("对象 ",label_name," 没有找到. 错误代码 = ",GetLastError()); ObjectCreate(0,label_name,OBJ_LABEL,0,0,0); ObjectSetInteger(0,label_name,OBJPROP_XDISTANCE,200); ObjectSetInteger(0,label_name,OBJPROP_YDISTANCE,300); ObjectSetInteger(0,label_name,OBJPROP_COLOR,White); ObjectSetString(0,label_name,OBJPROP_TEXT,UP); ObjectSetString(0,label_name,OBJPROP_FONT,"Wingdings"); ObjectSetInteger(0,label_name,OBJPROP_FONTSIZE,10); ObjectSetDouble(0,label_name,OBJPROP_ANGLE,-45); ObjectSetInteger(0,label_name,OBJPROP_SELECTABLE,false); ChartRedraw(0); } }
我们可以使用 OOP 范式来实施它:
1. 声明 CChartObjectLabel 对象:
CChartObjectLabel label;
2. 对象上的操作:
int OnInit() { //--- label.Create(0, label_name, 0, 0); label.X_Distance(200); label.Y_Distance(300); label.Color(White); label.Description(UP); label.Font("Wingdings"); label.FontSize(10); label.Angle(-45); label.Selectable(false); //--- return(0); }
如您所见,主要区别在于我们不再对字符串 label_ name 进行操作:
string label_name="my_OBJ_LABEL_object";
并使用 label_name 作为一个参数调用 ObjectSetInteger()、ObjectGetInteger()、ObjectSetDouble()、ObjectGetDouble() 函数,但我们声明 CChartObjectLabel 对象并使用其方法。这不仅更容易记忆、在实施上更符合逻辑,而且编写也更为快速。
当将点 (.) 放置在对象实例后时,MQL5 代码编辑器为我们提供了代码完成功能。没有必要反复遍历 MQL5 文档以查看要放置的 OBJPROP 属性以设置或获取指定属性。
与上文中介绍的 CChartObjectTrend 类相似,获取或设置半直线向左或向右足以声明 CChartObjectTrend 对象和调用 RayRight() 或 RayLeft() 方法:
CChartObjectTrend trendline; trendline.RayRight(true);
2. ProgressBar
我们将要实施的首个组件是 ProgressBar。进度条显示部分操作的进度,范围从 0 到 x%。
为使其更加可靠,让我们将最大值限制为任何正整数值,而不是 100。我们需要一个根据进度值改变其大小的彩条。我首先想到的是使用两个矩形,但我采用了另一种方式:使用两个 CChartObjectEdit 对象,其中一个位于另一个的内部,并具有不同的背景颜色。
如此一来就简化了编码和可放入进度条以显示其值的文本的添加。如果我们的进度条可根据需要呈水平或垂直就好了。
2.1. ProgressBar 实施
CChartObjectProgress 类派生自 CChartObjectEdit 类。 我添加了私有内部变量以保存值和值的限制:m_value、m_min、m_max。 进度条的方向设置为整数值并由 m_direction 变量保存。颜色由 m_color 变量保存。Type() 方法返回 OBJ_EDIT 值,因为无论如何,没有识别到符合我们目的的值。读者可能注意到 CChartObjectEdit m_bar 变量位于类定义的内部 - 这是基于 m_value 改变其大小的内部条。其他变量 m_name 和 m_chart 在内部为 m_bar 变量保存值。 class CChartObjectProgressBar : public CChartObjectEdit { private: int m_value; int m_min; int m_max; int m_direction; color m_color; CChartObjectEdit m_bar; string m_name; long m_chart_id; public: int GetValue(); int GetMin(); int GetMax(); void SetValue(int val); void SetMin(int val); void SetMax(int val); void SetColor(color bgcol,color fgcol); bool Create(long chart_id,string name,int window,int X,int Y, int sizeX,int sizeY,int direction); //--- 识别对象方法 virtual int Type() const { return(OBJ_EDIT); }