✔️ GUI 图形库MT4©: https://www.mql5.com/en/market/product/206760
✔️ GUI 图形库MT5©: https://www.mql5.com/en/market/product/206761
✔️ 完整的文档、元素库和图像转代码工具⁵: https://www.betasoft.dev/gui-graphic-library
持仓表、订单单和实时图表。
GUI图形库为您的智能交易系统和指标提供完整的界面:窗口、标签页、菜单、表格、图表、选择器、对话框和交易小部件。所有元素都绘制在同一个画布上,同一段代码可在MetaTrader 4和MetaTrader 5中运行,整个API仅包含15个函数。
本指南将引导您从下载文件到创建第一个可运行的面板,并逐步介绍您最常用的功能。每个代码示例都仅使用公共头文件,因此您可以将其粘贴到自己的程序中。
78 个元素中的一小部分:按钮、输入框、滑块和标签页。
1. 开始之前
- 适用于 Windows 系统的 MetaTrader 4 或 MetaTrader 5。字体和图标遵循 Windows 显示比例(100%、125%、150% 和 200%)。
- MetaEditor,用于编译演示程序和您自己的程序。
- 终端选项中无需允许任何内容:该库不使用 DLL,不发出任何 Web 请求,也不使用任何终端全局变量。
- MT4 和 MT5 是不同的产品。请安装与您的终端匹配的版本。
2. 安装
- 在终端中选择“文件”,然后选择“打开数据文件夹”。
- 打开 MQL5 文件夹(MetaTrader 5)或 MQL4 文件夹(MetaTrader 4)。
- 将每个文件复制到上表所示的文件夹中:Libraries、Include、Experts 和 Indicators。
- 在 MetaEditor 中打开每个演示,然后按 F7。结果应显示 0 个错误,0 个警告。
- 回到终端,刷新导航器(右键单击,刷新),以便显示新程序。
文件夹结构应如下所示:
MQL5/
Include/GUI_Graphic_Library.mqh
Libraries/GUI_Graphic_Library.ex5
Experts/GUI_Graphic_Library_FullDemo.mq5
GUI_Graphic_Library_ElementTests.mq5
Indicators/GUI_Graphic_Library_IndicatorWindow.mq5
GUI_Graphic_Library_IndicatorChart.mq5
MQL4/ the same files with .mq4 and .ex4
请勿重命名库文件。包含文件会按原名加载它。
安装后检查
| 查看 | 在哪里 |
|---|---|
| .ex5(或 .ex4)文件位于库中 | 数据文件夹 |
| .mqh 文件位于 Include 目录中。 | 数据文件夹 |
| 演示程序编译无误 | 元编辑器 |
| 演示中会在图表上显示一个窗口。 | 图表 |
| “专家”选项卡中没有“不支持”的行。 | 终端,工具箱 |
GUI_Graphic_Library.mqh 文件里有什么?
包含文件特意做得很小。在导入块上方,它声明了枚举类型(对象类型、属性、事件、主题和图标)。下面的导入块加载已编译的库并列出其 15 个函数。MetaTrader 5 加载 .ex5 文件,而 MetaTrader 4 加载 .ex4 文件,由编译器选择。您只需包含该文件,无需对其进行任何编辑。
#ifdef __MQL5__ #import "\\Market\\GUI_Graphic_Library.ex5" #else #import "\\Market\\GUI_Graphic_Library.ex4" #endif string Gui_Version(); bool Gui_Create( const long chart= 0 , const string name= "GUI_Graphic_Library" , const int subwin= 0 ); void Gui_Destroy(); void Gui_ChartEvent( const int id, const long lparam, const double dparam, const string sparam); void Gui_Timer(); void Gui_Update( const bool force= false ); bool Gui_NextEvent(ENUM_GUI_EVENT &event, int &sender, long &lparam, double &dparam, string &sparam); int Gui_Add( const ENUM_GUI_OBJECT type, const int parent, const string name, const string text, const int x, const int y, const int w, const int h); int Gui_Set( const int id, const ENUM_GUI_PROP prop, const string s= "" , const double a= EMPTY_VALUE , const double b= EMPTY_VALUE , const double c= EMPTY_VALUE , const double d= EMPTY_VALUE ); string Gui_Get( const int id, const ENUM_GUI_PROP prop, const string s= "" , const double a= EMPTY_VALUE , const double b= EMPTY_VALUE ); double Gui_GetNum( const int id, const ENUM_GUI_PROP prop, const string s= "" , const double a= EMPTY_VALUE , const double b= EMPTY_VALUE ); int Gui_SetArray( const int id, const ENUM_GUI_PROP prop, const double &values[], const double a= EMPTY_VALUE ); int Gui_AddImage( const string name, const uint &argb[], const int w, const int h); int Gui_Find( const string name); void Gui_BringToFront(); #import
这15个功能按出现顺序排列:
| 功能 | 它的作用 | 你称之为 |
|---|---|---|
| Gui_Version | 返回库版本信息(文本格式)。 | 任何地方 |
| Gui_创建 | 在图表上启动图形用户界面。传入参数 0 表示当前图表,传入程序名称,传入指标所在的子窗口编号。如果程序运行成功,则返回 true。 | OnInit |
| Gui_Destroy | 移除图形用户界面及其绘制的所有内容。 | OnDeinit |
| Gui_ChartEvent | 将图表事件(鼠标、键盘、点击)传递给库。 | 图表事件 |
| Gui_Timer | 运行库中的计时器:动画、提示信息、计数器。 | 定时器 |
| Gui_更新 | 重绘已更改的部分。传递 true 参数则重绘所有内容。 | 每个处理程序结束 |
| Gui_NextEvent | 从队列中获取下一个事件(点击、更改、对话框结果、交易请求)。当队列为空时返回 false。 | 事件循环 |
| Gui_Add | 创建一个元素并返回其 id。你需要提供类型、父元素、名称、文本以及 x、y、宽度和高度。 | OnInit |
| Gui_Set | 更改元素的属性或执行操作。如果元素不支持此操作,则返回 -1 并记录一行日志。 | 任何地方 |
| Gui_Get | 将属性读取为文本。 | 任何地方 |
| Gui_GetNum | 将属性值读取为数字。 | 任何地方 |
| Gui_SetArray | 将数字列表发送给元素,例如整个图表系列。 | 任何地方 |
| Gui_AddImage | 从 ARGB 像素数组中注册图像,以便元素可以显示它。网站上的“图像转代码”工具会将 PNG 文件转换为此数组。 | OnInit |
| Gui_Find | 根据名称查找元素 ID。 | 任何地方 |
| Gui_BringToFront | 将图形用户界面移动到您之后绘制的图表对象上方。 | 创建图表对象之后 |
这就是全部界面。本指南中的其他所有内容都是这15个调用组合而成的。
3. 运行完整演示
- 打开图表。例如,使用 1280 x 720 像素或更大的窗口可以显示更多信息。
- 将导航器中的 GUI_Graphic_Library_FullDemo 拖到图表上。
- 使用顶部的选项卡:首页、用例、按钮、输入、选择器、数据、图表、布局、反馈、交易和设置。
除非您将输入参数 InpLiveTrading 设置为 true,否则演示程序不会发送订单。在真实账户中,请将其关闭。如果您关闭主窗口,智能交易系统将自动关闭。
当您想要一次查看一个元素时,请使用 GUI_Graphic_Library_ElementTests:单击其选择器窗口中的组。
一个完全由库中的元素构建的仪表盘。
4. 你的第一个面板
这是一个完整的智能交易系统:一个包含交易手数输入框、“买入”按钮和状态栏的窗口。它不会进行交易,只会显示一条信息。
#include <GUI_Graphic_Library.mqh> int wMain, spLots, btnBuy, lblInfo; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int OnInit () { if (!Gui_Create( 0 , "MyPanel" )) return INIT_FAILED ; // 0 = this chart Gui_Set( 0 , GUI_PROP_THEME, "" , GUI_THEME_DARK); wMain = Gui_Add(GUI_OBJ_WINDOW, 0 , "wMain" , "My panel" , 20 , 40 , 300 , 170 ); Gui_Set(wMain, GUI_PROP_THEME_BUTTON, "" , true ); // sun / moon button Gui_Set(wMain, GUI_PROP_MAIN_WINDOW, "" , true ); // close asks to remove the program spLots = Gui_Add(GUI_OBJ_SPIN, wMain, "spLots" , "" , 10 , 10 , 280 , 30 ); Gui_Set(spLots, GUI_PROP_RANGE, "" , 0.01 , 50 , 0.01 , 2 ); // min, max, step, digits Gui_Set(spLots, GUI_PROP_VALUE, "" , 0.10 ); Gui_Set(spLots, GUI_PROP_SUFFIX, "lots" ); btnBuy = Gui_Add(GUI_OBJ_BUTTON, wMain, "btnBuy" , "BUY" , 10 , 50 , 280 , 40 ); Gui_Set(btnBuy, GUI_PROP_STYLE, "" , GUI_BUTTON_SUCCESS); Gui_Set(btnBuy, GUI_PROP_ICON, "" , GUI_ICON_ARROW_UP); lblInfo = Gui_Add(GUI_OBJ_LABEL, wMain, "lblInfo" , "Ready" , 10 , 100 , 280 , 20 ); Gui_Set(lblInfo, GUI_PROP_DIM, "" , true ); Gui_Set( 0 , GUI_PROP_REDRAW); return INIT_SUCCEEDED ; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void ProcessEvents() { ENUM_GUI_EVENT ev; int sender; long l; double d; string s; while (Gui_NextEvent(ev, sender, l, d, s)) if (ev == GUI_EVENT_CLICK && sender == btnBuy) { double lots = Gui_GetNum(spLots, GUI_PROP_VALUE); Gui_Set(lblInfo, GUI_PROP_TEXT, "Buy " + DoubleToString (lots, 2 ) + " lots" ); Gui_Set( 0 , GUI_PROP_TOAST, "Buy|" + DoubleToString (lots, 2 ) + " lots" , GUI_NOTICE_SUCCESS, 3000 ); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnDeinit ( const int r) { Gui_Destroy(); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnTimer () { Gui_Timer(); ProcessEvents(); Gui_Update(); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnChartEvent ( const int id, const long &l, const double &d, const string &s) { Gui_ChartEvent(id, l, d, s); ProcessEvents(); Gui_Update(); }
模式始终不变:
- OnInit 会创建 GUI 及其元素。
- OnChartEvent 和 OnTimer 将事件传递给库,读取队列并调用 Gui_Update。
- OnDeinit 会销毁 GUI。
5. 图书馆的思维方式
- ID。Gui_Add 函数返回一个整数 ID。您可以保存所需的 ID,或者稍后使用 Gui_Find("name") 函数按名称查找。ID 0 代表 GUI 本身:主题、提示信息、对话框、计数器等。
- 父元素。每个元素都会被添加到某个父元素(窗口或容器)中。窗口、菜单和价格标签使用父元素 0。对于选项卡,其父元素是选项卡本身,返回的 ID 是您添加子元素的页面。
- 属性。Gui_Set(id, property, text, a, b, c, d) 用于更改属性或执行操作。文本放在 text 参数中;数字、颜色和枚举值分别放在 a 到 d 参数中。Gui_Get 用于读取文本,Gui_GetNum 用于读取数字。
- 事件。该库会将用户操作添加到队列中。使用 Gui_NextEvent 读取队列。
- 坐标以像素为单位,缩放比例为 100%。该库会自动将其乘以 Windows 显示缩放比例。
如果传递的属性是元素不支持的,也不会出错:调用返回 -1,并在 Experts 日志中写入一行。
6. 你最常做的任务
读取用户输入或选择的内容
string name=Gui_Get(edName,GUI_PROP_TEXT); double lots=Gui_GetNum(spLots,GUI_PROP_VALUE); int tab =( int )Gui_GetNum(tabs,GUI_PROP_SELECTED);
标签页
int t=Gui_Add(GUI_OBJ_TABS,win, "tabs" , "" , 10 , 10 , 600 , 300 ); int pOrders =Gui_Add(GUI_OBJ_TAB,t, "" , "Orders" , 0 , 0 , 0 , 0 ); // returns the page int pHistory=Gui_Add(GUI_OBJ_TAB,t, "" , "History" , 0 , 0 , 0 , 0 ); Gui_Add(GUI_OBJ_BUTTON,pOrders, "b1" , "Close all" , 10 , 10 , 120 , 30 );
表格
int tb=Gui_Add(GUI_OBJ_TABLE,page, "tbl" , "" , 10 , 10 , 600 , 300 ); Gui_Set(tb,GUI_PROP_ADD_COLUMN, "Symbol" , 120 ,GUI_ALIGN_LEFT); Gui_Set(tb,GUI_PROP_ADD_COLUMN, "Strength" , 130 ,GUI_ALIGN_LEFT,GUI_COL_PROGRESS); Gui_Set(tb,GUI_PROP_ADD_BUTTON_COLUMN, "Action" , 100 ,GUI_BUTTON_PRIMARY); Gui_Set(tb,GUI_PROP_ADD_ROW, "EURUSD|64|Trade" ); Gui_Set(tb,GUI_PROP_SORT, "" , 0 , true );
单击按钮单元格会发送 GUI_EVENT_CELL_BUTTON 事件,其中 lparam 为行号,dparam 为列号。
图表
int ch=Gui_Add(GUI_OBJ_LINECHART,page, "chart" , "Price" , 10 , 10 , 500 , 260 ); int ln=Gui_Set(ch,GUI_PROP_ADD_SERIES, "Close" , clrDodgerBlue ); // returns the series index double closes[]; CopyClose ( _Symbol , PERIOD_H1 , 0 , 100 ,closes); Gui_SetArray(ch,GUI_PROP_SERIES,closes,ln); // a whole series at once int cd=Gui_Add(GUI_OBJ_CANDLECHART,page, "cd" , _Symbol , 10 , 280 , 500 , 260 ); Gui_Set(cd,GUI_PROP_LOAD_BARS, _Symbol , 80 ); Gui_Set(cd,GUI_PROP_ADD_MA, "" , 20 , clrDodgerBlue ); Gui_Set(cd,GUI_PROP_ADD_BANDS, "" , 20 , 2.0 );
对话和祝酒
enum { CMD_CLOSE_ALL= 500 }; Gui_Set( 0 ,GUI_PROP_CONFIRM, "Close all|Close every position?|Close|Cancel" ,CMD_CLOSE_ALL); // later, in the event loop: if (ev==GUI_EVENT_DIALOG && Gui_GetNum(sender,GUI_PROP_CMD)==CMD_CLOSE_ALL && l== 0 ) CloseAll(); // l = button index, -1 = cancelled Gui_Set( 0 ,GUI_PROP_TOAST, "Order|Filled" ,GUI_NOTICE_SUCCESS, 3000 );
主题和颜色
Gui_Set( 0 ,GUI_PROP_THEME, "" ,GUI_THEME_MIDNIGHT); // DARK, LIGHT, MIDNIGHT, HIGHCONTRAST, SOFT Gui_Set( 0 ,GUI_PROP_ACCENT, "" , clrOrange ); Gui_Set( 0 ,GUI_PROP_RADIUS, "" , 10 );
记住窗口和价值观
Gui_Set( 0 ,GUI_PROP_AUTO_LAYOUT, "" , true ); // load now, save when the GUI is destroyed Gui_Set( 0 ,GUI_PROP_LOAD_VALUES); // in OnInit Gui_Set( 0 ,GUI_PROP_SAVE_VALUES); // in OnDeinit
两者都使用小型文本文件,未使用终端全局变量。
每秒都做点什么
Gui_Set( 0 ,GUI_PROP_COUNTER, "refresh" , 1000 , true ); // name, ms, repeat // in OnTimer: if (Gui_GetNum( 0 ,GUI_PROP_COUNTER_DONE, "refresh" )!= 0 ) RefreshNumbers();
7. 一个带有自定义订单功能的交易面板
订单单、持仓面板和风险计算器会读取账户和交易品种,然后向您提供事件信息。它们本身不会发送订单。用户点击“买入”或“卖出”按钮后,具体执行什么操作,由您决定。
#include <GUI_Graphic_Library.mqh> #ifdef __MQL5__ #include <Trade\Trade.mqh> CTrade g_trade; #endif input bool InpLiveTrading = false ; // send real orders int g_ticket = 0 ; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int OnInit () { if (!Gui_Create( 0 , "GUI_TradePanel" )) return INIT_FAILED ; int w = Gui_Add(GUI_OBJ_WINDOW, 0 , "w" , "Trade" , 20 , 40 , 360 , 260 ); Gui_Set(w, GUI_PROP_MAIN_WINDOW, "" , true ); g_ticket = Gui_Add(GUI_OBJ_ORDERTICKET, w, "ticket" , _Symbol , 10 , 10 , 340 , 212 ); Gui_Set(g_ticket, GUI_PROP_LOTS, "" , 0.10 ); Gui_Set(g_ticket, GUI_PROP_STOP_POINTS, "" , 300 ); Gui_Set(g_ticket, GUI_PROP_TP_POINTS, "" , 600 ); Gui_Set(g_ticket, GUI_PROP_SHOW_LINES, "" , true ); // SL and TP lines on the chart Gui_Set( 0 , GUI_PROP_CLEAR_EVENTS); return INIT_SUCCEEDED ; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void MyTrade( const bool buy, const double lots, const double sl, const double tp) { if (!InpLiveTrading) { Print ( "Trading is off. Would " , buy ? "buy " : "sell " , lots, " lots" ); return ; } #ifdef __MQL5__ if (buy) g_trade.Buy(lots, _Symbol , 0.0 , sl, tp); else g_trade.Sell(lots, _Symbol , 0.0 , sl, tp); #else if (buy) OrderSend ( _Symbol , OP_BUY, lots, Ask, 3 , sl, tp, "GUI" , 0 , 0 , clrGreen ); else OrderSend ( _Symbol , OP_SELL, lots, Bid, 3 , sl, tp, "GUI" , 0 , 0 , clrRed ); #endif } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void ProcessEvents() { ENUM_GUI_EVENT ev; int sender; long l; double d; string s; while (Gui_NextEvent(ev, sender, l, d, s)) if (ev == GUI_EVENT_TRADE) // l: 0 buy, 1 sell d: lots s: "sl|tp" prices { string p[]; StringSplit (s, '|' , p); double sl = ( ArraySize (p) > 0 ) ? StringToDouble (p[ 0 ]) : 0.0 ; double tp = ( ArraySize (p) > 1 ) ? StringToDouble (p[ 1 ]) : 0.0 ; MyTrade(l == 0 , d, sl, tp); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnDeinit ( const int r) { Gui_Destroy(); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnTimer () { Gui_Timer(); ProcessEvents(); Gui_Update(); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnChartEvent ( const int id, const long &l, const double &d, const string &s) { Gui_ChartEvent(id, l, d, s); ProcessEvents(); Gui_Update(); }
先在模拟账户上测试。下单前,还要检查手数是否符合交易品种的最小、最大和步长要求,以及止损距离是否符合经纪商的止损水平。
位置的工作方式相同:添加 GUI_OBJ_POSITIONS,然后响应 GUI_EVENT_POSITION(lparam 是票据,dparam 为 1 表示关闭,为 2 表示修改)。
8. 在指标中使用它
指示器可以在其自身的子窗口中绘制 GUI。将该窗口的编号传递给 Gui_Create:
#property indicator_separate_window int OnInit () { int sub= ChartWindowFind (); Gui_Create( 0 , "GUI_MyIndicator" ,sub); // add windows and controls as usual return INIT_SUCCEEDED ; }
要在价格图表上绘制指标,请使用子窗口 0。两个指标演示都是完整的示例。每个程序和图表都有一个独立的图形用户界面 (GUI),因此请为每个程序指定一个 GUI 名称。
9. MetaTrader 4 和 MetaTrader 5
| 话题 | MetaTrader 4 | MetaTrader 5 |
|---|---|---|
| 库文件 | .ex4 | .ex5 |
| 上下文菜单 | 长按鼠标左键,或按住 Ctrl 键并单击 | 右键单击 |
| 鼠标滚轮 | 未通过终端发送。请使用滚动条。 | 作品 |
| 市场深度 | 自行添加关卡 | 阅读市场报告 |
| 经济日历 | 自行添加行 | 来自终端的负载 |
| 打字 | 内置美国地图 | 每种键盘布局都有效 |
10. 如果某件事行不通
| 问题 | 该怎么办 |
|---|---|
| 图表上没有任何显示。 | 检查 Gui_Create 是否返回 true,并阅读“专家”选项卡的最后几行。 |
| 编译器无法打开 GUI_Graphic_Library.mqh | 包含文件不在与程序相同的数据文件夹的 Include 文件夹中。 |
| 程序无法在运行时加载库。 | 库中缺少 .ex5 或 .ex4 文件,或者其名称已更改。 |
| 代码中更改的值不会显示出来。 | 在处理程序的末尾调用 Gui_Update()。 |
| “专家”选项卡显示该属性不受支持。 | 该元素不存在此属性。请查阅 API 文档。 |
| 两个程序在同一张图表上展开较量 | 在 Gui_Create 中给每个组件命名。 |
| 图表线覆盖了图形用户界面 | 创建图表对象后调用 Gui_BringToFront()。 |
| 文字太小或太大 | 设置 Gui_Set(0,GUI_PROP_SCALE,"",1.5),或者在更改 Windows 缩放比例后重新启动终端。 |
| 你想看看图书馆在做什么 | 启用 Gui_Set(0,GUI_PROP_DEBUG,"",true) 以启用调试叠加层。 |
11. 提示
- 在每个处理程序结束时调用 Gui_Update()。它只会重绘已更改的部分。
- 隐藏的标签页和折叠的窗口不会导致页面重绘,因此通过定时器更新它们成本很低。
- 如果运行多个图表,请使用 GUI_PROP_MAX_FPS 来限制帧速率。
- 在 OnInit 的末尾使用 GUI_PROP_CLEAR_EVENTS 来删除在构建面板时排队的事件。
- 使用网站上的“图像转代码”工具,将 PNG 徽标或图标转换为 Gui_AddImage 的数组。
- 新的枚举值只会在末尾添加,因此使用旧版包含文件构建的程序在更新后仍能继续运行。请同时替换库文件和包含文件。
12. 下一步去哪里
- 元素库、安装指南、API 参考、图像转代码和帮助: https://www.betasoft.dev/gui-graphic-library
- MetaTrader 5 版本: https://www.mql5.com/en/market/product/206761
- MetaTrader 4 版本: https://www.mql5.com/en/market/product/206760
欢迎您的意见。如有任何疑问或改进建议,请在产品评论区留言或通过 MQL5.com给我发送消息。





