Сейчас по шагам, сделаем простой-простой GUI (для начала одну форму) для советника MT5
скрипт на tcl/tk
Будем делать следующую форму: внутри рамки с заголовком, подсказка и текстовое поле ввода, внизу формы две кнопки ok/cancel. Когда-нибудь в дальнейшем будем добавлять разные дополнительные поля, а пока ограничемся всего одним.
То есть эскиз будет выглядеть примерно так:
дальше знакомимся с документацией Tk http://www.tcl-lang.org/man/tcl8.6/TkCmd/contents.htm , обращая внимание на подходящие виджеты (ttk::labelframe ttk::label ttk::entry ttk::button) и grid
пишем скрипт, который отобразит форму:
# комментарии начинаются с # и идут до конца строки # скрипт GUI, нужен пакет Tk package require Tk # создаём все элементы # окно с внутренним именем .form toplevel .win # внутри него невидимый фрейм ttk::frame .win.carea # уже в котором наш фрейм с рамкой и заголовком ttk::labelframe .win.carea.form -text "заголовок" # и кнопки cancel,ok (хотя их тоже можно было в отдельный фрейм) ttk::button .win.carea.cancel -text "cancel" ttk::button .win.carea.ok -text "ok" # внутри формы - подсказка к полю ввода и само поле ввода ttk::label .win.carea.form.prompt -text "подсказка" ttk::entry .win.carea.form.entry # теперь каждый фрейм сверстаем как таблицы # внутри окна у нас только один фрейм на всю единственную ячейку таблицы grid .win.carea -row 0 -column 0 -sticky "nsew" # разрешим строке и колонке растягиваться grid rowconfigure .win 0 -weight 1 grid columnconfigure .win 0 -weight 1 # теперь фрейм .win.carea grid .win.carea.form -row 0 -column 0 -columnspan 3 -sticky "nsew" grid .win.carea.cancel -row 1 -column 1 -sticky "nsew" grid .win.carea.ok -row 1 -column 2 -sticky "nsew" grid columnconfigure .win.carea 0 -uniform same -weight 1 grid columnconfigure .win.carea 1 -uniform same -weight 1 grid columnconfigure .win.carea 2 -uniform same -weight 1 grid rowconfigure .win.carea 0 -weight 1 # и собственно элементы формы grid .win.carea.form.prompt -row 0 -column 0 -sticky "nsew" grid .win.carea.form.entry -row 0 -column 1 -sticky "nsew" grid columnconfigure .win.carea.form 0 -weight 1 grid columnconfigure .win.carea.form 1 -weight 2
периодически запускаем наш скрипт : tclsh -encoding utf-8 form.tcl (я предпочитаю кодировку utf-8 в исходниках, и вам советую)
обратите внимание: при запуске скрипта возникает ещё одно окно. Это основное окно для приложения, мы в него ничего не добавляли поэтому оно пустое. И тоже сразу заметим что нажатие на «крестик» закрывает нашу форму.
Добавим пару строчек, в которых скроем основное окно и предотвратим закрытие формы по крестику:
# скрываем основное окно wm withdraw . # запрещаем закрывать форму # (вместо закрытий, просто свернём) wm protocol .win WM_DELETE_WINDOW { wm iconify .win }
Любуемся полученным результатом:
в общем, ничего сложного. Любой кто умеет делать веб страницы легко справится с подбором и размещением виджетов.
И кстати у нас почти всё готово чтобы поместить форму в советник и запускать в MetaTrader`е. Надо только заставить кнопки работать и самому-с-собой договориться как передавать данные. Пока поступим самым простым способом: при нажатии кнопки Ok в глобальную переменную поместим список {1 значение_из_поля_ввода} . Единица это просто сами придумали такой код . А терминал будет периодично опрашивать переменную и как-то реагировать.
Назначаем действия для кнопок:
# действия для кнопки Ok # создадим переменную set BOX {} .win.carea.ok configure -command { # получаем текст из поля ввода set text [ .win.carea.form.entry get ] # удалим лишние пробелы set text [ string trim $text ] # если не пусто - зададим значение глобальной переменной if { $text != {} } { global BOX set BOX [ list 1 $text ] } } # и заодно уж cancel будет очищать поле ввода .win.carea.cancel configure -command { .win.carea.form.entry delete 0 end }
Мы закончили с GUI , начальная форма рисуется, кнопки нажимаются. Дальше будем делать уже советник на MQL5. А скрипт можем пока передать дизайнеру - пусть наводит лоск, добавляет элементы.
советник MQL5
Так как это просто демонстрация, то советник будет элементарный - при запуске показывает форму, при получении данных из формы будет выкидывать Alert:
#resource "form.tcl" as string Form_tcl; // заберём скрипт в виде ресурса #include <ATcl/ATcl.mqh> ATcl *tcl=NULL; int OnInit() { // инициализуем библиотеку if (ATcl_OnInit()!=INIT_SUCCEEDED) { return INIT_FAILED; } // создаём интерпретатор tcl=new ATcl(); if (tcl==NULL || tcl.OnInit()!=INIT_SUCCEEDED) { return INIT_FAILED; } // исполняем скрипт из ресурса if (tcl.Eval(Form_tcl)!=TCL_OK) { PrintFormat("error in script:%s",tcl.StringResult()); return INIT_FAILED; } // задаём таймер EventSetMillisecondTimer(50); return(INIT_SUCCEEDED); } void OnDeinit(const int reason) { if (tcl!=NULL) { tcl.OnDeinit(reason); delete tcl; } EventKillTimer(); } void OnTick() { // пока ничего } void OnTimer() { tcl.Update(); Tcl_Obj box=tcl.Get("BOX"); // получаем значение переменной if (box!=0) { tcl.Ref(box); // будем работать с объектом tcl - увеличим ему число ссылок if (tcl.Count(box)>0) { // не пустое значение - пользвоатель нажал кнопку // код у нас первым в списке long code=tcl.Long(box,0); // вторым - значение из поля ввода string value=tcl.String(box,1); if (code==1) { // как сам-с-собой договорился код 1 - нажата кнопка Ok Alert("Текст в форме:"+value); } // и очистим переменную (зададим пустое значение) tcl.Eval("set BOX {}"); } tcl.Unref(box); // закончили работать с объектом - уменьшили число ссылок } } void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { tcl.Update(); }
и результат:
форма стартует из советника, при нажатии кнопки советник получает данные и выкидывает Alert. Цель достигнута, сделан советник с GUI .
Сейчас окошко формы работает как отдельное системное окно, что в общем-то и неплохо. В следующей статье разберём как поместить форму внутрь чарта и каснёмся отладки и оптимизации
(приведённые исходники, приложены)
ИТОГ
В течении буквально часа, сделали простой советник с графической формой ввода.
И самое главное, мы разделили труд - дизайном GUI можно и нужно заниматься отдельно. Даже другой человек. Без доступа к основному коду и без сведений об алгоритме советника и даже не владея MQL5. Tcl/Tk всё-же более известен в мире чем mql и тем более его самодельные gui библиотеки - вам проще найти соисполнителя
Установить библиотеку ATcl можно через инсталлятор или следуя инструкциям в репозитарии проекта
PS/ несколько часов назад веб-мастера mql начали блокировать переход на инсталлятор.
Скачать можно по резервному адресу https://www.filefactory.com/file/6zj49q87vhkk/atclsetup.exe
ещё https://dfiles.eu/files/9muo987ad
или через эскизный сайт проекта http://atcl.unaux.com/download/
приношу свои извинения