sunyu007
CC
 楼主 | 发表于 2026-7-21 17:29:58 | 显示全部楼层
goldenclaw 发表于 2026-7-19 08:32
可视化拖拽生成MQL面板的思路很赞,解决了MQL原生GUI开发效率低的问题。想问下生成的代码是否支持MT4和MT5 ...

一共生成三个文件:UIControls、UIEvents、Generated。作用分别如下:
一、面板的所有事件控制,由UIControls文件独立管控,代码固定无需修改。
二、事件响应,由UIEvents文件管理,在其中添加事件代码即可。(需要修改)
三、Generated文件即为EA,可改成你的EA名称。(需要修改)
1、在初始化中,生成面板;
2、对开关按钮、单选控件、复选控件、下拉控件,在EA文件中添加判断代码 if(PCt3_Tgl1_State==1){ };
3、EA逻辑添加到OnTick中。
举报

点赞 评论 使用道具

sunyu007
CC
 楼主 | 发表于 2026-7-23 09:32:58 | 显示全部楼层
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[3]; // 复选项: 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[i] = 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);
}
}
//+------------------------------------------------------------------+
举报

点赞 评论 使用道具

sunyu007
CC
 楼主 | 发表于 2026-7-23 09:49:02 | 显示全部楼层
面板中实时数据的设置
填充数据.png

面板示例
面板演示.png

面板演示.rar 压缩包中,包含4个文件
Generated_UI.ex5  编译好的示例EA,可加载在MT5中运行
Generated_UI.mq5 示例源码文件
UIEvents_mq5.mqh 面板控件的设置文件
面板示例.JSON 面板设计文件(在MQL面板设计器中打开)
还有一个UIControls_mq5.mqh文件没有在压缩包中(这是此套面板工具的重要文件,需要授权购买)
filetype

面板演示.rar

68.96 KB, 下载次数: 4, 下载积分: 活跃度 -5  [下载]

举报

点赞 评论 使用道具

12
发新帖
EA交易
您需要登录后才可以评论 登录 | 立即注册