캔버스 멋지다! - 페이지 84

 
Martin Moreno #:
캔버스 클래스로 사용자 인터페이스를 만들고 싶습니다. 유일한 문제는 차트에서 대시보드를 움직일 수 있게 만드는 방법을 모른다는 것입니다.
많이 검색했지만 예제를 찾지 못했습니다. 힌트를 주시면 감사하겠습니다.


이 문서에서 시작하실 수 있습니다: https: //www.mql5.com/en/articles/12751

Improve Your Trading Charts With Interactive GUI's in MQL5 (Part I): Movable GUI (I)
Improve Your Trading Charts With Interactive GUI's in MQL5 (Part I): Movable GUI (I)
  • www.mql5.com
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.
 
Samuel Manoel De Souza #:

이 문서에서 시작할 수 있습니다: https: //www.mql5.com/en/articles/12751

좋아요...정말 감사합니다!

 
Martin Moreno #:
캔버스 클래스로 사용자 인터페이스를 만들고 싶습니다. 유일한 문제는 차트에서 대시보드를 움직일 수 있게 만드는 방법을 모른다는 것입니다.
많이 검색했지만 예제를 찾지 못했습니다. 힌트를 주시면 감사하겠습니다.


이미 4년 전에 예시를 드렸습니다 :))

트레이딩, 자동 트레이딩 시스템 및 테스트 트레이딩 전략에 관한 포럼

모든 개체를 하나의 개체로 변환하는 방법

니콜라이 셈코, 2019.10.05 22:39

실제로 캔버스가 해결책입니다.

그리고 캔버스는 언뜻 보기보다 훨씬 쉽습니다.

다음은 많은 창이 있는 하나의 객체 OBJ_BITMAP_LABEL이 있는 인디케이터(MQL5 및 MQL4)의 원시적인 예입니다.

#property indicator_chart_window
#include <Canvas\iCanvas.mqh> //https://www.mql5.com/ru/code/22164 - MQL5
                              //https://www.mql5.com/en/code/23840 - MQL4

struct win {
   int               x;
   int               y;
   int               width;
   int               height;
   uint              clr;
};
win wnd[30];
int OnInit() {
   for (int i=0; i<ArraySize(wnd); i++) {
      wnd[i].width=rand()%200+70;
      wnd[i].height=rand()%150+50;
      wnd[i].x=rand()%(W.Width-wnd[i].width);
      wnd[i].y=rand()%(W.Height-wnd[i].height);
      wnd[i].clr=ARGB(255,rand()%150+100,rand()%150+100,rand()%150+100);
   }
   ShowAllWind();
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+

int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) {
   return(rates_total);
}

//+------------------------------------------------------------------+

void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam) {
   static bool click = false;
   static int x_mouse=0, y_mouse=0;
   static int focus=-1, xfocus=0, yfocus=0;
   int x=(int)lparam;
   int y=(int)dparam;
   if (sparam!="1" && click) focus=-1;
   if (sparam=="1" && !click) {
      focus=-1;
      for (int i=ArraySize(wnd)-1; i>=0; i--) {
         if (wnd[i].x<x && wnd[i].y<y && wnd[i].x+wnd[i].width>x && wnd[i].y+20>y) {
            focus=i;
            xfocus=x;
            yfocus=y;
            break;
         }
      }
      if (focus>=0) ChartSetInteger(0,CHART_MOUSE_SCROLL,false);
      else ChartSetInteger(0,CHART_MOUSE_SCROLL,true);
   }
   click=(sparam=="1")?true:false;
   if (id==CHARTEVENT_MOUSE_MOVE && focus>=0) {
      wnd[focus].x+=x-xfocus;
      wnd[focus].y+=y-yfocus;
      xfocus=x;
      yfocus=y;
      ShowAllWind();
   }
   if (id==CHARTEVENT_CHART_CHANGE) ShowAllWind();
}

//+------------------------------------------------------------------+

void ShowAllWind() {
   Canvas.Erase();
   for (int i=0; i<ArraySize(wnd); i++) {
      Canvas.FillRectangle(wnd[i].x,wnd[i].y,wnd[i].x+wnd[i].width,wnd[i].y+wnd[i].height,ARGB(255,GETRGBR(wnd[i].clr)*0.5,GETRGBG(wnd[i].clr)*0.5,GETRGBB(wnd[i].clr)*0.5));
      Canvas.FillRectangle(wnd[i].x+3,wnd[i].y+23,wnd[i].x+wnd[i].width-3,wnd[i].y+wnd[i].height-3,wnd[i].clr);
      Canvas.FillRectangle(wnd[i].x+3,wnd[i].y+3,wnd[i].x+wnd[i].width-3,wnd[i].y+20,ARGB(255,GETRGBR(wnd[i].clr)*0.7,GETRGBG(wnd[i].clr)*0.7,GETRGBB(wnd[i].clr)*0.7));
   }
   Canvas.Update();
}
//+------------------------------------------------------------------+

이 새로운 문서에서는 정보 패널을 구현하는 또 다른 옵션인

https://www.mql5.com/ru/articles/13179

파일:
 
Nikolai Semko #:
예를 들어, 여기에서는 이를 명확하게 보여주는 스크립트를 스케치했습니다. 오른쪽은 이 빠른 알고리즘이고 왼쪽은 제 알고리즘입니다(약 4~10배 느림).
.
니콜라이 셈코, 안녕하세요. 이 예제 https://www.mql5.com/ru/forum/227736/page66#comment_20456641 에서 Bmp 크기 조정 (축소)을 시연했습니다.

Bmp 그림을 줄일 수 있지만 캔버스는 같은 크기로 유지됩니다. 같은 이유로 사진을 확대할 수 없으며 원본 크기, 즉 캔버스 크기로 잘립니다.

배열을 완전히 이해하지 못해서 설명해 주시거나 코드가 있는 예제를 보여 주실 수 있나요?

1. 이미지 확대

2. 그림을 축소하거나 확대한 경우 그림의 크기와 동일한 캔버스입니다.

감사합니다.

 
Vitaliy Kuznetsov #:
니콜라이 셈코 님, 안녕하세요. 이 예제 https://www.mql5.com/ru/forum/227736/page66#comment_20456641 에서는 Bmp 크기 조정(축소)을 시연했습니다.

Bmp 그림을 줄일 수 있지만 캔버스는 동일한 크기로 유지됩니다. 같은 이유로 이미지를 확대할 수 없으며 원본 크기, 즉 캔버스 크기로 잘립니다.

배열을 완전히 이해하지 못해서 설명해 주시거나 코드가 있는 예제를 보여 주실 수 있나요?

1. 이미지 확대

2. 그림을 축소하거나 확대한 경우 그림의 크기와 동일한 캔버스입니다.

감사합니다.

안녕하세요,
CCanvas에는 Resize() 함수가 있습니다.
 
Vitaliy Kuznetsov #:

멋지고 유용합니다. 궁금한 게 있는데, MT4에서도 사용할 수 있나요?

안타깝게도 MQL4에서는 리소스를 배열로 첨부할 수 없습니다. 하지만 다른 모든 것은 작동합니다.
물론 하드 탬버린을 통해 구현할 수 있습니다. 예를 들어 PNG 이미지를 BMP 파일에 삽입하고, 즉 PNG 시작 부분에 BMP 헤더를 추가하고, PNG 자체를 bmp 이미지로 전달합니다(즉, 이러한 BMP를 열면 투명도가 다른 컬러 픽셀의 노이즈가 발생함). 그런 다음 이 "bmp 파일"을 MQL4의 리소스로 첨부합니다. 이것은 시장에 필요할 수 있으므로 ex4에는 이미 더 밀도가 높은 PNG 형식의 이미지가 포함되어 있습니다.
참고: png는 동일한 BMP 이미지보다 품질 손실 없이 약 10배 더 작으며 전체 투명도를 지원합니다.
ex5(ex4) 파일의 실제 bmp 리소스는 압축된 형식으로 저장되지만 그보다 훨씬 적은 양은 아닙니다. 정확히 확인할 필요가 있습니다.
 

모두 안녕하세요. 이 코드에도 관심이 있습니다. 그러나 Resize()를 사용할 때 작동하지 않습니다. 어쩌면 다른 순서로 수행해야 할 수도 있습니다.

 
Vladimir Nikolaychuk #:

모두 안녕하세요. 이 코드에도 관심이 있습니다. 그러나 Resize()를 사용할 때 작동하지 않습니다. 어쩌면 다른 순서로 수행해야 할 수도 있습니다.

좋아요, 나중에 예제를 보여드리겠습니다.
하지만 저는 전체 차트에 대해 하나의 캔버스로 작업하는 것을 선호합니다. 95%의 경우 정당화됩니다.
 
Nikolai Semko #:
잠시 후에 예를 들어보겠습니다.
하지만 저는 전체 차트에 대해 하나의 캔버스로 작업하는 것을 선호합니다. 이것은 95%의 경우 정당화됩니다.

코드 예제를 알려주시면 정말 감사하겠습니다. 미리 감사드립니다...

 
Nikolai Semko #:
잠시 후에 예를 들어보겠습니다.
하지만 저는 전체 차트에 대해 하나의 캔버스로 작업하는 것을 선호합니다. 이것은 95%의 경우 정당화됩니다.

다음은 마우스를 움직이면 캔버스의 위치가 바뀌고 크기가 변경되는 png.mql 라이브러리를 기반으로 한 예제입니다. 마우스 포인터가 가로로 중앙에 있으면 이미지의 원래 크기에 해당하고, 왼쪽으로 가면 축소, 오른쪽으로 가면 확대됩니다.
png.mql의 변수 C와 _만 비공개에서 공개로 다시 던져야 했습니다. 따라서 이 라이브러리가 이미 설치되어 있는 경우 덮어써야 합니다.
이 예제에는 두 가지 작동 모드가 있습니다(입력 변수 bool resize_canvas):

  • 이미지 크기가 조정될 때마다 캔버스 크기 조정 포함
  • 이미지 크기가 조정될 때마다 캔버스 크기를 조정하지 않는 경우. 캔버스의 초기 크기는 작업 논리에 따라 가능한 최대 이미지 크기와 동일하게 설정됩니다.
안타깝게도 MQL5의 첫 번째 모드에는 캔버스 크기를 변경하지 않는 한 가지 방법으로 만 치료할 수있는 이미지 깜박임의 고대 버그가 있습니다. 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)

input bool resize_canvas = false;
int chart_width,chart_height;


//+------------------------------------------------------------------+
int OnInit() {
   img.Resize(resize_canvas?10:img.width*MAX_ZOOM); // формируем массив _bmp[] максимального размера в режиме без изменения размера canvas
   ChartSetInteger(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);
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
}
//+------------------------------------------------------------------+
void OnTick() {
}
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &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);
   }
}



PNG
PNG
  • www.mql5.com
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.
파일: