Обсуждение статьи "Сделайте торговые графики лучше с интерактивным графическим интерфейсом на основе MQL5 (Часть III): Простой перемещаемый торговый интерфейс"
Наглядный пример использования ООП ради ООП.
Получилось громоздко и не удобно (ИМХО). Но работает, а это уже хорошо :)
Нужно добавить OBJPROP_ZORDER иначе кнопки нажимаются через раз.
void Button::Create(string name, int xDis = 0, int yDis = 0, int xSize = 0, int ySize = 0) { ObjectCreate(0, name, OBJ_BUTTON, 0, 0, 0); ObjectSetInteger(0, name, OBJPROP_XDISTANCE, xDis); ObjectSetInteger(0, name, OBJPROP_YDISTANCE, yDis); ObjectSetInteger(0, name, OBJPROP_XSIZE, xSize); ObjectSetInteger(0, name, OBJPROP_YSIZE, ySize); ObjectSetInteger(0, name, OBJPROP_ZORDER, 1); _name = name; } //+------------------------------------------------------------------+
Наглядный пример использования ООП ради ООП.
Получилось громоздко и не удобно (ИМХО). Но работает, а это уже хорошо :)
Нужно добавить OBJPROP_ZORDER иначе кнопки нажимаются через раз.
это вообще не ООП. Это повторно завёрнутые в классы методы терминала.
если программист захочет сделать иной GUI (модный http, через WebSocket освещённый в прочих статьях), то ничего сделать не сможет. Просто выбросит вообще весь код из статьи и напишет иной.
чтобы коренным образом поменять визуальную часть, но на тех-же ObjectCreate(xx) - всё равно придётся переписывать просто всё.
или как отключить GUI, чтобы он не занимал процессор на VDS-ке
Где reusability ? Почему GUI перемежается с прочим кодом..Про стили, хотя-бы цвета, можно и не говорить
Используя библиотеки статьи, код типичного советника стал короче ? а вот хренушки, не для того писано :-)
это вообще не ООП. Это повторно завёрнутые в классы методы терминала.
если программист захочет сделать иной GUI (модный http, через WebSocket освещённый в прочих статьях), то ничего сделать не сможет. Просто выбросит вообще весь код из статьи и напишет иной.
чтобы коренным образом поменять визуальную часть, но на тех-же ObjectCreate(xx) - всё равно придётся переписывать просто всё.
или как отключить GUI, чтобы он не занимал процессор на VDS-ке
Где reusability ? Почему GUI перемежается с прочим кодом..Про стили, хотя-бы цвета, можно и не говорить
Используя библиотеки статьи, код типичного советника стал короче ? а вот хренушки, не для того писано :-)
Ну обсуждать цвета, думаю здесь не совсем корректно.
А вот то что кнопки бай и селл расположены наоборот, это может ввести пользователя в заблуждение.
Не понятно зачем отключать GUI, если это панель для ручной торговли. Хотя, если это не торговая панель, а информационная, то да, лучше продумать отключение.
Мне понравилось как организованна функция RectangleLabel::OnEvent и RectangleLabel::Add, красиво, понятно, читаемо.
Я в своих панельках использовал такой же принцип, но у меня код был какой то корявый, что ли. В общем не красивый. Вот и решил использовать код из статьи для новой панельки.
Панелька в итоге получилась, но времени убил на это больше, чем если бы писал с нуля.
В общем вывод такой: статья интересная, полезная, но код в статье частично не продуман.
Ну обсуждать цвета, думаю здесь не совсем корректно.
А вот то что кнопки бай и селл расположены наоборот, это может ввести пользователя в заблуждение.
Не понятно зачем отключать GUI, если это панель для ручной торговли. Хотя, если это не торговая панель, а информационная, то да, лучше продумать отключение.
Мне понравилось как организованна функция RectangleLabel::OnEvent и RectangleLabel::Add, красиво, понятно, читаемо.
Я в своих панельках использовал такой же принцип, но у меня код был какой то корявый, что ли. В общем не красивый. Вот и решил использовать код из статьи для новой панельки.
Панелька в итоге получилась, но времени убил на это больше, чем если бы писал с нуля.
В общем вывод такой: статья интересная, полезная, но код в статье частично не продуман.
есть тьма проработанных методик с красивыми стрелочками "как реализовать UI чтобы не было мучительно больно" :-) MVC и подобные. Так там фронт (win,gtk,qt,web) подчас можно менять лёгким движением руки.
ни одно не было реализовано в MQL. Тут всё прибивается наглухо гвоздями, хуже TurboVision - там хоть так-же классы от адама, но там есть модели
отдельные лица годами(!!) пишут про "легко и просто" и "простой интерфейс", но ровно то-же самое что в этой статье. Масса кода не облегчающего ничего. Единственный эффект - бонус на счёт автора.
есть тьма проработанных методик с красивыми стрелочками "как реализовать UI чтобы не было мучительно больно" :-) MVC и подобные. Так там фронт (win,gtk,qt,web) подчас можно менять лёгким движением руки.
ни одно не было реализовано в MQL. Тут всё прибивается наглухо гвоздями, хуже TurboVision - там хоть так-же классы от адама, но там есть модели
отдельные лица годами(!!) пишут про "легко и просто" и "простой интерфейс", но ровно то-же самое что в этой статье. Масса кода не облегчающего ничего. Единственный эффект - бонус на счёт автора.
Ой, у меня одно только упоминание об MVC вызывает ужас.
Это осталось с тех пор как я, жене сайт, интернет магазина делал на движке OcStore.
К тому времени как пришло хоть какое то понимание как это работает, я был наполовину седой)))
Давайте не будем судить строго, эта серия статей ориентирована на начинающих.
Статьи написаны понятно и доходчиво, а написать понятно это не такая уж простая задача.
Автор, справляется с этой задачей на отлично.
Ой, у меня одно только упоминание об MVC вызывает ужас.
Это осталось с тех пор как я, жене сайт, интернет магазина делал на движке OcStore.
К тому времени как пришло хоть какое то понимание как это работает, я был наполовину седой)))
Давайте не будем судить строго, эта серия статей ориентирована на начинающих.
Статьи написаны понятно и доходчиво, а написать понятно это не такая уж простая задача.
Автор, справляется с этой задачей на отлично.
у меня вот воспоминание о том чтобы считать ширину/высоту и относительные и абс.координаты всратой кнопки повергают в уныние :-)
2024 год - но пр прежнему, пользователь библиотеки должен считать пиксели
приведёный диалог, в виде : поле ввода объёмов и две кнополки buy/sell
как приведённый диалог решает проблемы с допустимостью объёмов и возможностью торговли ? да, лоты не могут быть менее минимума, инкременируются по шагам и не более максимума. Buy/Sell не всегда возможны.
Хоть намётки на решения есть ? нету
КАК ? в рукопашку-же...внутри советника вручную рулить всеми опциями конкретного GUI. Ничуть не лучше использольвания напрямую функций терминала.
между ObjectSetXXX(chart,objName,propertyName,propertyValue) и obj.SetInteger(value) - разница покрывается дефайнами, тут не нужно никакое ООП
---
это уже не в плане статьи, это вообще про "писателей". Лучше-бы читали
I have a memory of calculating the width/height and the relative and absolute coordinates of a button, which is depressing :-)
2024 - but still, the library user must count pixels
the given dialogue, in the form: volume input field and two buy/sell buttons
How does the above dialogue solve problems with the admissibility of volumes and the possibility of trading? Yes, lots cannot be less than the minimum, they are incremented in steps and no more than the maximum. Buy/Sell is not always possible. Are there any hints of solutions? There is not
HOW? in hand-to-hand combat... inside the advisor, manually control all the options of a specific GUI. It's no better than using the terminal functions directly.
between ObjectSetXXX(chart,objName,propertyName,propertyValue) and obj.SetInteger(value) - the difference is covered by definitions, no OOP is needed here
---
This is no longer in terms of the article, it's generally about “writers”. It would be better if they read
Just one thing, I would like to point out is, this series was not written for this Buy/Sell GUI rather it was written for any GUI and this Buy/Sell GUI acts as an simple example.
Thanks for giving the series such thoughts, would appreciate suggestions.
Regards
у меня вот воспоминание о том чтобы считать ширину/высоту и относительные и абс.координаты всратой кнопки повергают в уныние :-)
2024 год - но пр прежнему, пользователь библиотеки должен считать пиксели
приведёный диалог, в виде : поле ввода объёмов и две кнополки buy/sell
как приведённый диалог решает проблемы с допустимостью объёмов и возможностью торговли ? да, лоты не могут быть менее минимума, инкременируются по шагам и не более максимума. Buy/Sell не всегда возможны.
Хоть намётки на решения есть ? нету
КАК ? в рукопашку-же...внутри советника вручную рулить всеми опциями конкретного GUI. Ничуть не лучше использольвания напрямую функций терминала.
между ObjectSetXXX(chart,objName,propertyName,propertyValue) и obj.SetInteger(value) - разница покрывается дефайнами, тут не нужно никакое ООП
---
это уже не в плане статьи, это вообще про "писателей". Лучше-бы читали
Блин, у меня это всего третья панелька, первые две вспоминать не охота, если их увидит какой нибудь кодер, мне будет стыдно.
Хотелось бы сделать сейчас так, чтоб в следующий раз не пришлось столько с ней возится.
Сейчас в подключаемом файле оставил только класс с кодом для перетаскивания всех элементов панели и кучка гетов.
class CreateObject { private: string _name; // Name of the rectangle label int previousMouseState, mlbDownX, mlbDownY, mlbDownXDistance, mlbDownYDistance; // Mouse state tracking variables bool movingState; // State for whether the object is moving string addedNames[]; // Array of added names long addedXDisDiffrence[], addedYDisDiffrence[]; // Arrays to store added distance differences void Destroy() {for(int i = 0; i < (int)addedNames.Size(); i++)ObjectDelete(0, addedNames[i]); ObjectDelete(0, _name);} // Destroy method for rectangle label public: CreateObject(void); // Constructor ~CreateObject(void); // Destructor void SetName(string name) {_name = name;} string GetText(string name) {return ObjectGetString(0, name, OBJPROP_TEXT);} // Method to retrieve the text content long GetType(string name) {return ObjectGetInteger(0, name, OBJPROP_TYPE);} double GetPrice(string name) {return ObjectGetDouble(0, name, OBJPROP_PRICE);} void OnEvent(int id, long lparam, double dparam, string sparam); // Event handler method void Add(string name); // Method to add a name to the object }; //+------------------------------------------------------------------+ CreateObject::CreateObject(void) {} //+------------------------------------------------------------------+ CreateObject::~CreateObject(void) {Destroy();} //+------------------------------------------------------------------+ //| Event handling for mouse movements | //+------------------------------------------------------------------+ void CreateObject::OnEvent(int id, long lparam, double dparam, string sparam) { // Handle mouse movement events for dragging the rectangle label if(id == CHARTEVENT_MOUSE_MOVE && lparam > 20 && dparam > 20 && lparam < ChartGetInteger(0, CHART_WIDTH_IN_PIXELS) - 20 && dparam < ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS) - 20) { int X = (int)lparam; int Y = (int)dparam; int MouseState = (int)sparam; string name = _name; int XDistance = (int)ObjectGetInteger(0, name, OBJPROP_XDISTANCE); int YDistance = (int)ObjectGetInteger(0, name, OBJPROP_YDISTANCE); int XSize = (int)ObjectGetInteger(0, name, OBJPROP_XSIZE); int YSize = (int)ObjectGetInteger(0, name, OBJPROP_YSIZE); if(previousMouseState == 0 && MouseState == 1) { mlbDownX = X; mlbDownY = Y; mlbDownXDistance = XDistance; mlbDownYDistance = YDistance; if(X >= XDistance && X <= XDistance + XSize && Y >= YDistance && Y <= YDistance + YSize) { movingState = true; } } if(movingState) { ChartSetInteger(0, CHART_MOUSE_SCROLL, false); ObjectSetInteger(0, name, OBJPROP_XDISTANCE, mlbDownXDistance + X - mlbDownX); ObjectSetInteger(0, name, OBJPROP_YDISTANCE, mlbDownYDistance + Y - mlbDownY); for(int i = 0; i < ArraySize(addedNames); i++) { ObjectSetInteger(0, addedNames[i], OBJPROP_XDISTANCE, mlbDownXDistance + X - mlbDownX - addedXDisDiffrence[i]); ObjectSetInteger(0, addedNames[i], OBJPROP_YDISTANCE, mlbDownYDistance + Y - mlbDownY - addedYDisDiffrence[i]); } ChartRedraw(0); } if(MouseState == 0) { movingState = false; ChartSetInteger(0, CHART_MOUSE_SCROLL, true); } previousMouseState = MouseState; } } //+------------------------------------------------------------------+ //| Method to add an object by name to the rectangle label | //+------------------------------------------------------------------+ void CreateObject::Add(string name) { // Add a new object by name to the rectangle label and track distances ArrayResize(addedNames, ArraySize(addedNames) + 1); ArrayResize(addedXDisDiffrence, ArraySize(addedXDisDiffrence) + 1); ArrayResize(addedYDisDiffrence, ArraySize(addedYDisDiffrence) + 1); addedNames[ArraySize(addedNames) - 1] = name; addedXDisDiffrence[ArraySize(addedXDisDiffrence) - 1] = ObjectGetInteger(0, _name, OBJPROP_XDISTANCE) - ObjectGetInteger(0, name, OBJPROP_XDISTANCE); addedYDisDiffrence[ArraySize(addedYDisDiffrence) - 1] = ObjectGetInteger(0, _name, OBJPROP_YDISTANCE) - ObjectGetInteger(0, name, OBJPROP_YDISTANCE); } //+------------------------------------------------------------------+
А ниже у меня просто функции для рисования объектов, скопипастил из справки, вроде так удобнее всё в одной кучке.
В итоге код в советнике был длинный, стал широкий, в общем поменял шило на мыло.
Ещё один подключаемый файл с часто используемыми торговыми функциями, типа посчитать все позиции, нормализовать цену, закрыть позиции, ну и т.д.
Но это всё равно как то громоздко и не универсально.
В следующей панельке всё равно по новой придётся высчитывать каждое поле и писать обработку для этих полей(кнопки/поле ввода).
И я что то ну никак не могу придумать схемку как сделать это всё более универсально.
Может, чего доброго подскажите по оформлению кода?
Но это всё равно как то громоздко и не универсально.
В следующей панельке всё равно по новой придётся высчитывать каждое поле и писать обработку для этих полей(кнопки/поле ввода).
И я что то ну никак не могу придумать схемку как сделать это всё более универсально.
Может, чего доброго подскажите по оформлению кода?
Наиболее практичный и универсальный вариант - дизайнить формы визуально, не заботясь о коде раскладки вообще - этим как раз должны заниматься классы. Одно из возможных решений было в статье.

- www.mql5.com

- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Опубликована статья Сделайте торговые графики лучше с интерактивным графическим интерфейсом на основе MQL5 (Часть III): Простой перемещаемый торговый интерфейс:
В этой серии статей мы исследуем интеграцию интерактивных графических интерфейсов в перемещаемые торговые панели на MQL5. В третьей части мы используем наработки из предыдущих частей, чтобы превратить статические торговые панели в динамические.
Для начала давайте вспомним, что мы рассмотрели в предыдущих двух частях:
В третьей части мы сосредоточимся на улучшении наших панелей путем интеграции в них графических интерфейсов. Без графического интерфейса панели не будут служить своему прямому назначению.
Автор: Kailash Bai Mina