【高效MQL面板设计工具】10分钟生成美观的MQL面板,且包含复杂的交互逻辑。
最后由 sunyu007 于 2026-6-27 08:59 编辑MQL UI设计器产品介绍1、独立:市面首款可脱离MQL原生环境,独立完成MQL界面布局设计的专用工具2、高效:可视化开发模式,实现所见即所得的设计效果,大幅提升EA界面的开发效率,操作便捷、高效直观。3、简单:软件操作门槛极低,无需繁琐的代码编写,新手也能快速上手,仅需十几分钟,便可快速搭建出精致美观、布局规整的EA界面,彻底颠覆传统低效的开发模式。4、功能齐全:面板控件支持拖拽移动、下拉选择、单选、复选等多元交互功能,同时配备带加减调控的数值输入框,功能全面且贴合实际开发场景。5、核心优势:软件可自动生成复杂的界面交互逻辑,无需人工逐一编码调试。
重大更新(v1.28版 )
面板支持历史数据回测
MQL面板设计器,已升级至1.31版
新增功能:对面板的实时数据,自动命名变量并自动刷新
面板控件的设置,在自动生成的文件为 UIEvents.mqh 中,分为几个部分:
1、开关按钮的变量
2、数据填充的变量
3、自动更新开关变量的状态函数 UI_UpdateStates()
4、刷新数据填充值 RefreshData()
5、点击按钮的功能定义 OnUIButtonClick()
6、输入框值的获取。
设置起来非常简单。对已有EA进行改造也相当简单。
示例代码如下:
//+------------------------------------------------------------------+
//| UIEvents.mqh |
//+------------------------------------------------------------------+
#property strict
//--- 开关状态变量,可在Generated_UI中直接引用
bool PCt2_Tgl5_State = false; // 开关按钮: PCt2_Tgl5
bool PCt2_Tgl1_State = false; // 开关按钮: PCt2_Tgl1
bool PCt2_Tgl2_State = false; // 开关按钮: PCt2_Tgl2
bool PCt2_Tgl6_State = false; // 开关按钮: PCt2_Tgl6
bool PCt2_Tgl7_State = false; // 开关按钮: PCt2_Tgl7
bool PCt2_Tgl8_State = false; // 开关按钮: PCt2_Tgl8
bool PCt2_Tgl3_State = false; // 开关按钮: PCt2_Tgl3
bool PCt2_Tgl9_State = false; // 开关按钮: PCt2_Tgl9
int PCt3_Cmb1_State = -1; // 选项框: PCt3_Cmb1
bool PCt2_Tgl4_State = false; // 开关按钮: PCt2_Tgl4
int PCt5_Cmb2_State = -1; // 选项框: PCt5_Cmb2
int PCt5_Rad1_State = -1; // 单选项: PCt5_Rad1
bool PCt5_Chk1_State; // 复选项: PCt5_Chk1
//--- 数据填充变量 (用于文本标签)
double 每单仓位;
int 底仓数量;
int 网格间隔;
int 止盈格数;
double 止损价;
double 平仓利润;
double 持仓风险;
double 补仓风险;
double 预估风险;
int 净值;
int 多单数量;
double 多单仓位;
double 多单盈亏;
int 空单数量;
double 空单仓位;
double 网格价;
double 空单盈亏;
int 总数量;
double 多空仓位差;
double 总盈亏;
double 多单成本价;
double 空单成本价;
double 综合成本价;
int 余额;
//--- 自动更新状态函数
void UI_UpdateStates() {
PCt2_Tgl5_State = UIGetToggleState("PCt2_Tgl5");
PCt2_Tgl1_State = UIGetToggleState("PCt2_Tgl1");
PCt2_Tgl2_State = UIGetToggleState("PCt2_Tgl2");
PCt2_Tgl6_State = UIGetToggleState("PCt2_Tgl6");
PCt2_Tgl7_State = UIGetToggleState("PCt2_Tgl7");
PCt2_Tgl8_State = UIGetToggleState("PCt2_Tgl8");
PCt2_Tgl3_State = UIGetToggleState("PCt2_Tgl3");
PCt2_Tgl9_State = UIGetToggleState("PCt2_Tgl9");
PCt3_Cmb1_State = UIGetComboSelectedIndex("PCt3_Cmb1", "持仓多网,持仓空网,限价多网,限价空网,突破多网,突破空网");
PCt2_Tgl4_State = UIGetToggleState("PCt2_Tgl4");
PCt5_Cmb2_State = UIGetComboSelectedIndex("PCt5_Cmb2", "A,B,C");
PCt5_Rad1_State = UIGetRadioSelectedIndex("PCt5_Rad1", 3);
for(int i=0; i<3; i++) PCt5_Chk1_State = UIGetCheckState("PCt5_Chk1", i);
}
//--- 刷新数据函数 (刷新需要填充数据的文本标签) ---
void RefreshData() {
ObjectSetString(0,"PCt3_LblData1",OBJPROP_TEXT, DoubleToString(每单仓位,2)); //每单仓位
ObjectSetString(0,"PCt3_LblData2",OBJPROP_TEXT, IntegerToString(底仓数量)); //底仓数量
ObjectSetString(0,"PCt3_LblData3",OBJPROP_TEXT, IntegerToString(网格间隔)); //网格间隔
ObjectSetString(0,"PCt3_LblData4",OBJPROP_TEXT, IntegerToString(止盈格数)); //止盈格数
ObjectSetString(0,"PCt3_LblData5",OBJPROP_TEXT, DoubleToString(止损价,2)); //止损价
ObjectSetString(0,"PCt3_LblData6",OBJPROP_TEXT, DoubleToString(平仓利润,2)); //平仓利润
ObjectSetString(0,"PCt3_LblData7",OBJPROP_TEXT, DoubleToString(持仓风险,2)); //持仓风险
ObjectSetString(0,"PCt3_LblData8",OBJPROP_TEXT, DoubleToString(补仓风险,2)); //补仓风险
ObjectSetString(0,"PCt3_LblData9",OBJPROP_TEXT, DoubleToString(预估风险,2)); //预估风险
ObjectSetString(0,"PCt4_LblData10",OBJPROP_TEXT, IntegerToString(净值)); //净值
ObjectSetString(0,"PCt4_LblData11",OBJPROP_TEXT, IntegerToString(多单数量)); //多单数量
ObjectSetString(0,"PCt4_LblData12",OBJPROP_TEXT, DoubleToString(多单仓位,2)); //多单仓位
ObjectSetString(0,"PCt4_LblData13",OBJPROP_TEXT, DoubleToString(多单盈亏,2)); //多单盈亏
ObjectSetString(0,"PCt4_LblData14",OBJPROP_TEXT, IntegerToString(空单数量)); //空单数量
ObjectSetString(0,"PCt4_LblData15",OBJPROP_TEXT, DoubleToString(空单仓位,2)); //空单仓位
ObjectSetString(0,"PCt3_LblData16",OBJPROP_TEXT, DoubleToString(网格价,2)); //网格价
ObjectSetString(0,"PCt4_LblData17",OBJPROP_TEXT, DoubleToString(空单盈亏,2)); //空单盈亏
ObjectSetString(0,"PCt4_LblData18",OBJPROP_TEXT, IntegerToString(总数量)); //总数量
ObjectSetString(0,"PCt4_LblData19",OBJPROP_TEXT, DoubleToString(多空仓位差,2)); //多空仓位差
ObjectSetString(0,"PCt4_LblData20",OBJPROP_TEXT, DoubleToString(总盈亏,2)); //总盈亏
ObjectSetString(0,"PCt4_LblData21",OBJPROP_TEXT, DoubleToString(多单成本价,2)); //多单成本价
ObjectSetString(0,"PCt4_LblData22",OBJPROP_TEXT, DoubleToString(空单成本价,2)); //空单成本价
ObjectSetString(0,"PCt4_LblData23",OBJPROP_TEXT, DoubleToString(综合成本价,2)); //综合成本价
ObjectSetString(0,"PCt4_LblData24",OBJPROP_TEXT, IntegerToString(余额)); //余额
}
//--- 点击按钮的功能设定
void OnUIButtonClick(string btnName) {
if(btnName == "PCt1_Btn1") {
Print("按钮 PCt1_Btn1 止损线 被点击");
}
if(btnName == "PCt1_Btn2") {
Print("按钮 PCt1_Btn2 开仓布网 被点击");
}
if(btnName == "PCt1_Btn3") {
Print("按钮 PCt1_Btn3 价格 被点击");
}
if(btnName == "PCt1_Btn4") {
Print("按钮 PCt1_Btn4 挂限价网 被点击");
}
if(btnName == "PCt1_Btn5") {
Print("按钮 PCt1_Btn5 多改盈 被点击");
}
if(btnName == "PCt1_Btn10") {
Print("按钮 PCt1_Btn10 多改损 被点击");
}
if(btnName == "PCt1_Btn6") {
Print("按钮 PCt1_Btn6 空改盈 被点击");
}
if(btnName == "PCt1_Btn11") {
Print("按钮 PCt1_Btn11 多改损 被点击");
}
if(btnName == "PCt1_Btn7") {
Print("按钮 PCt1_Btn7 手动加多 被点击");
}
if(btnName == "PCt1_Btn12") {
Print("按钮 PCt1_Btn12 手动加空 被点击");
}
if(btnName == "PCt1_Btn8") {
Print("按钮 PCt1_Btn8 手动平多 被点击");
}
if(btnName == "PCt1_Btn13") {
Print("按钮 PCt1_Btn13 手动平空 被点击");
}
if(btnName == "PCt2_Tgl5") {
Print("按钮 PCt2_Tgl5 √指标开多 被点击");
}
if(btnName == "PCt2_Tgl1") {
Print("按钮 PCt2_Tgl1 √指标平多 被点击");
}
if(btnName == "PCt2_Tgl2") {
Print("按钮 PCt2_Tgl2 √自动保本 被点击");
}
if(btnName == "PCt2_Tgl6") {
Print("按钮 PCt2_Tgl6 √指标开空 被点击");
}
if(btnName == "PCt2_Tgl7") {
Print("按钮 PCt2_Tgl7 √指标平空 被点击");
}
if(btnName == "PCt2_Tgl8") {
Print("按钮 PCt2_Tgl8 √自动保利 被点击");
}
if(btnName == "PCt2_Tgl3") {
Print("按钮 PCt2_Tgl3 √自动追踪 被点击");
}
if(btnName == "PCt2_Tgl9") {
Print("按钮 PCt2_Tgl9 √亏损加仓 被点击");
}
if(btnName == "PCt1_Btn9") {
Print("按钮 PCt1_Btn9 挂突破网 被点击");
}
if(btnName == "PCt3_Btn14") {
Print("按钮 PCt3_Btn14 删网 被点击");
}
if(btnName == "PCt2_Tgl4") {
Print("按钮 PCt2_Tgl4 √盈利加仓 被点击");
}
}
//--- 输入框输入内容 (实盘有效,回测中无法触发)
void OnUIEditEnd(string editName) {
if(editName == "PCt1_Spn3") {
string val = ObjectGetString(0, "PCt1_Spn3", OBJPROP_TEXT);
Print("输入框 PCt1_Spn3: ", val);
}
if(editName == "PCt1_Spn4") {
string val = ObjectGetString(0, "PCt1_Spn4", OBJPROP_TEXT);
Print("输入框 PCt1_Spn4: ", val);
}
if(editName == "PCt1_Spn5") {
string val = ObjectGetString(0, "PCt1_Spn5", OBJPROP_TEXT);
Print("输入框 PCt1_Spn5: ", val);
}
if(editName == "PCt1_Spn6") {
string val = ObjectGetString(0, "PCt1_Spn6", OBJPROP_TEXT);
Print("输入框 PCt1_Spn6: ", val);
}
if(editName == "PCt1_Spn1") {
string val = ObjectGetString(0, "PCt1_Spn1", OBJPROP_TEXT);
Print("输入框 PCt1_Spn1: ", val);
}
if(editName == "PCt1_Spn2") {
string val = ObjectGetString(0, "PCt1_Spn2", OBJPROP_TEXT);
Print("输入框 PCt1_Spn2: ", val);
}
}
//+------------------------------------------------------------------+
面板中实时数据的设置
面板示例
面板演示.rar 压缩包中,包含4个文件
Generated_UI.ex5编译好的示例EA,可加载在MT5中运行
Generated_UI.mq5 示例源码文件
UIEvents_mq5.mqh 面板控件的设置文件
面板示例.JSON 面板设计文件(在MQL面板设计器中打开)
还有一个UIControls_mq5.mqh文件没有在压缩包中(这是此套面板工具的重要文件,需要授权购买) 最佳用法:将生成的面板代码,丢给AI补充功能。 好东东,谢谢分享 这个楼主是真不错,感谢分享 下载了但是打不开不知道是什么原因
363528854 发表于 2026-6-27 03:31
下载了但是打不开不知道是什么原因
请下载最新版,解决了兼容的问题。
https://gitee.com/ccc-yuhong/mql-ui-designer/releases/download/v1.26/UI_Designer1.26.dist.rar 大哥这个是能自己写EA吗? 可爱多 发表于 2026-6-27 13:40
大哥这个是能自己写EA吗?
只能写面板,EA逻辑可以用AI帮你加。 sunyu007 发表于 2026-6-27 09:00
请下载最新版,解决了兼容的问题。
https://gitee.com/ccc-yuhong/mql-ui-designer/releases/download/v1 ...
下载这个显示有木马倍杀毒软件自动删除了 ksw168 发表于 2026-6-29 12:41
下载这个显示有木马倍杀毒软件自动删除了
个人开发,无法获得正规签名,可将文件放入信任名单。 下载老版本后,可在应用内自动更新。以后就不再贴新版下载链接了。
最新版v1.29,新增配色方案,极速配色。 视频介绍1
https://v.douyin.com/Fzv9GWkJkDA/ 复制此链接,打开Dou音搜索,直接观看视频!
视频介绍2
https://v.douyin.com/FTe1n2H09uE/ 复制此链接,打开Dou音搜索,直接观看视频! 感谢楼主分享,非常好的一个工具啊! 看着功能强大,先琢磨一段时间再说![得意] 多看多学总是不错的 必须赞一个 非常好的模版 看着功能强大。好人一生平安 可视化拖拽生成MQL面板的思路很赞,解决了MQL原生GUI开发效率低的问题。想问下生成的代码是否支持MT4和MT5双平台兼容?另外控件的事件回调机制是怎么处理的? goldenclaw 发表于 2026-7-19 08:32
可视化拖拽生成MQL面板的思路很赞,解决了MQL原生GUI开发效率低的问题。想问下生成的代码是否支持MT4和MT5 ...
既可生成MT4代码,也可生成MT5代码,随意
页:
[1]
2