Я хочу создать пользовательский интерфейс с помощью класса Canvas. Моя единственная проблема заключается в том, что я не знаю, как сделать приборную панель подвижной на графике.
Я много искал, но не нашел ни одного примера. Буду благодарен, если вы подскажете.
Unleash the power of dynamic data representation in your trading strategies or utilities with our comprehensive guide on creating movable GUI in MQL5. Dive into the core concept of chart events and learn how to design and implement simple and multiple movable GUI on the same chart. This article also explores the process of adding elements to your GUI, enhancing their functionality and aesthetic appeal.
Я хочу создать пользовательский интерфейс с помощью класса Canvas. Моя единственная проблема заключается в том, что я не знаю, как сделать приборную панель подвижной на графике.
Я много искал, но не нашел ни одного примера. Буду благодарен, если вы подскажете.
Nikolai Semko #: Вот например набросал скрипт, который это наглядно демонстрирует. Справа этот быстрый алгоритм, а слева мой (где-то в 4-10 раз медленее).
У меня получается уменьшать картинку Bmp, но полотно остаётся того-же размера. По той же причине я не могу увеличить картинку, она обрезается изначальными размерами, т.е. размером полотна.
В массивах не до конца разобрался, так что можешь мне объяснить, а лучше показать пример кодом:
1. Увеличение картинки
2. Полотно равное размеру картинки, если мы её уменьшили или увеличили.
У меня получается уменьшать картинку Bmp, но полотно остаётся того-же размера. По той же причине я не могу увеличить картинку, она обрезается изначальными размерами, т.е. размером полотна.
В массивах не до конца разобрался, так что можешь мне объяснить, а лучше показать пример кодом:
1. Увеличение картинки
2. Полотно равное размеру картинки, если мы её уменьшили или увеличили.
Круто и полезно. Ради интереса, это можно использовать в МТ4?
К сожалению в MQL4 нет возможности прикреплять ресурс как массив. Но все остальное работает.
Можно конечно реализовать через жёсткие бубны. Например, вставить PNG изображение в BMP файл, т.е в начало png добавить шапку BMP формата, а сам png передавать как растр bmp( т.е. если открыть такой BMP, то будет шум из цветных пикселей разной прозрачности). А потом прикрепить этот "bmp файл", как ресурс в MQL4. Это может понадобиться для маркета, чтобы ex4 уже содержал изображение более плотного формата png.
Для справки: png примерно в 10 раз меньше того же BMP изображения без потери качества, в добавок поддерживая полноценную прозрачность.
Правда сам bmp ресурс в ex5(ex4) файле хранится в уплотненном формате, но не на порядок меньше. Надо проверить точно.
Но я предпочитаю работать с одним холстом на весь чарт. Это оправдано в 95% случаев.
вот пример на основе библиотеки png.mql, когда при движении мышки меняется положение canvas и меняется его размер. Если указатель мышки находится по центру по горизонтали, то это соответствует оригинальному размеру изображения, если левее -уменьшение, правее - увеличение масштаба. Только мне пришлось в png.mql переменные C и _С перебросить из private в public. Поэтому необходимо перезаписать эту библиотеку, если она уже установлена. В этом примере есть два режима работы (input переменная bool resize_canvas):
с изменением размера Canvas каждый раз при изменении размера изображения
без изменением размера Canvas при изменении размера изображения. Изначальный размер Canvas устанавливается равным максимальному возможному размеру изображения по логике работы.
К сожалению, в первом режиме в MQL5 сидит древний баг моргания изображения, который лечится только одним способом - не менять размер canvas. Все мои попытки изменить функцию CCanvas.Resize() ни к чему не превели. Все также моргает. Может у кого-то получится :)) Именно поэтому предпочитаю использовать один холст на весь экран!
#define MAX_ZOOM 2#include <Canvas\png.mqh> //https://www.mql5.com/en/code/45439
CPng img("cubes.png"); // Get PNG from a file, create a canvas and display it on the screen at coordinates (X=500, Y=100)inputbool resize_canvas = false;
int chart_width,chart_height;
//+------------------------------------------------------------------+intOnInit() {
img.Resize(resize_canvas?10:img.width*MAX_ZOOM); // формируем массив _bmp[] максимального размера в режиме без изменения размера canvasChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,true);
chart_width = (int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS);
chart_height = (int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS);
img._CreateCanvas(chart_width/3, chart_height/3);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+voidOnDeinit(constint reason) {
}
//+------------------------------------------------------------------+voidOnTick() {
}
//+------------------------------------------------------------------+voidOnChartEvent(constint id,
constlong &lparam,
constdouble &dparam,
conststring &sparam) {
if (id == CHARTEVENT_MOUSE_MOVE) {
double new_width = img.width*(MAX_ZOOM*(double)lparam/chart_width);
img.Resize(new_width);
if (resize_canvas) { // режим с изменением размера canvas Моргает!!!img._C.Resize(img._width,img._height);ArrayCopy(img._C.m_pixels,img._bmp);
} else { // режим без изменения размера canvas не Мограет!!!img._C.Erase(0x00FFFFFF);for(int i =0; i++<img._height;) ArrayCopy(img._C.m_pixels,img._bmp,int(i*img.width*MAX_ZOOM),i*img._width,img._width);
}
img._C.Update();
img._MoveCanvas(int(lparam)/5, int(dparam)/5);
}
}
Forget about BMP files like a bad dream. Thanks to this library, you can now use the PNG format, which has a number of advantages, such as being more compact without losing image quality and maintaining transparency.
Вы можете начать с этой статьи: https: //www.mql5.com/en/articles/12751
Вы можете начать с этой статьи: https: //www.mql5.com/en/articles/12751
Отлично... Спасибо большое!
Я уже приводил пример 4 года назад :))
Форум о трейдинге, автоматических торговых системах и тестировании торговых стратегий
как преобразовать все объекты в 1 объект
Николай Семко, 2019.10.05 22:39
Действительно, Canvas - это решение.
И Canvas намного проще, чем кажется на первый взгляд.
Вот примитивный пример индикатора (MQL5 & MQL4) с одним объектом OBJ_BITMAP_LABEL, в котором много окон.
В этой новой статье - еще один вариант реализации информационных панелей.
https://www.mql5.com/ru/articles/13179

Вот например набросал скрипт, который это наглядно демонстрирует. Справа этот быстрый алгоритм, а слева мой (где-то в 4-10 раз медленее).
У меня получается уменьшать картинку Bmp, но полотно остаётся того-же размера. По той же причине я не могу увеличить картинку, она обрезается изначальными размерами, т.е. размером полотна.
В массивах не до конца разобрался, так что можешь мне объяснить, а лучше показать пример кодом:
1. Увеличение картинки
2. Полотно равное размеру картинки, если мы её уменьшили или увеличили.
Спасибо.
Nikolai Semko, привет. В этом примере https://www.mql5.com/ru/forum/227736/page66#comment_20456641 ты продемонстрировал изменение размера Bmp (уменьшение).
У меня получается уменьшать картинку Bmp, но полотно остаётся того-же размера. По той же причине я не могу увеличить картинку, она обрезается изначальными размерами, т.е. размером полотна.
В массивах не до конца разобрался, так что можешь мне объяснить, а лучше показать пример кодом:
1. Увеличение картинки
2. Полотно равное размеру картинки, если мы её уменьшили или увеличили.
Спасибо.
Круто и полезно. Ради интереса, это можно использовать в МТ4?
Доброго всем времени суток. Мне тоже интересен этот код. Но при использовании Resize() - не получается. Может как-то в другой последовательности надо.
Доброго всем времени суток. Мне тоже интересен этот код. Но при использовании Resize() - не получается. Может как-то в другой последовательности надо.
Хорошо, чуть позже дам пример.
Был-бы очень признателен за пример кода. Заранее спасибо...
Хорошо, чуть позже дам пример.
вот пример на основе библиотеки png.mql, когда при движении мышки меняется положение canvas и меняется его размер. Если указатель мышки находится по центру по горизонтали, то это соответствует оригинальному размеру изображения, если левее -уменьшение, правее - увеличение масштаба.
Только мне пришлось в png.mql переменные C и _С перебросить из private в public. Поэтому необходимо перезаписать эту библиотеку, если она уже установлена.
В этом примере есть два режима работы (input переменная bool resize_canvas):
Именно поэтому предпочитаю использовать один холст на весь экран!