Leinwand ist cool! - Seite 84

 
Martin Moreno #:
Ich möchte eine Benutzeroberfläche mit der Canvas-Klasse zu erstellen. Mein einziges Problem ist, dass ich nicht weiß, wie ich das Dashboard auf dem Diagramm beweglich machen kann.
Ich habe viel gesucht, aber kein Beispiel gefunden. Ich wäre Ihnen dankbar, wenn Sie einen Tipp geben könnten.


Sie könnten mit diesem Artikel beginnen: 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 #:

Sie könnten mit diesem Artikel beginnen: https: //www.mql5.com/en/articles/12751

Großartig...Vielen Dank!

 
Martin Moreno #:
Ich möchte eine Benutzeroberfläche mit der Canvas-Klasse zu erstellen. Mein einziges Problem ist, dass ich nicht weiß, wie ich das Dashboard auf dem Diagramm beweglich machen kann.
Ich habe viel gesucht, aber kein Beispiel gefunden. Ich wäre Ihnen dankbar, wenn Sie einen Tipp geben könnten.


Ich habe Ihnen bereits vor 4 Jahren ein Beispiel gegeben :))

Forum über Handel, automatisierte Handelssysteme und das Testen von Handelsstrategien

Wie kann man alle Objekte in 1 Objekt umwandeln?

Nikolai Semko, 2019.10.05 22:39

In der Tat, Canvas ist die Lösung.

Und Canvas ist viel einfacher, als es auf den ersten Blick scheint.

Hier ist ein primitives Beispiel für einen Indikator (MQL5 & MQL4) mit einem Objekt OBJ_BITMAP_LABEL, in dem es viele Fenster gibt.

#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();
}
//+------------------------------------------------------------------+

n diesem neuen Artikel finden Sie eine weitere Möglichkeit zur Implementierung von Informationspanels.

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

Dateien:
 
Nikolai Semko #:
Hier habe ich zum Beispiel ein Skript skizziert, das dies anschaulich demonstriert. Rechts ist dieser schnelle Algorithmus und links ist meiner (etwa 4-10 mal langsamer).
.
Nikolai Semko, hallo. In diesem Beispiel https://www.mql5.com/ru/forum/227736/page66#comment_20456641 haben Sie die Größenänderung (Verkleinerung) von Bmps demonstriert.

Ich kann das Bmp-Bild verkleinern, aber die Leinwand bleibt in der gleichen Größe. Aus dem gleichen Grund kann ich das Bild auch nicht vergrößern, es wird auf die ursprüngliche Größe, d.h. die Größe der Leinwand, beschnitten.

Ich verstehe Arrays nicht ganz, können Sie mir das erklären, oder besser ein Beispiel mit Code zeigen:

1. Bildvergrößerung

2. Eine Leinwand, die der Größe des Bildes entspricht, wenn wir es verkleinert oder vergrößert haben.

Wir danken Ihnen.

 
Vitaliy Kuznetsov #:
Nikolai Semko, hallo. In diesem Beispiel https://www.mql5.com/ru/forum/227736/page66#comment_20456641 haben Sie die Größenänderung (Verkleinerung) von Bmp demonstriert.

Ich kann das Bmp-Bild verkleinern, aber die Leinwand bleibt die gleiche Größe. Aus dem gleichen Grund kann ich das Bild nicht vergrößern, es wird um die ursprüngliche Größe, d.h. die Größe der Leinwand, beschnitten.

Ich verstehe Arrays nicht ganz, können Sie mir das erklären, oder besser ein Beispiel mit Code zeigen:

1. Bildvergrößerung

2. Eine Leinwand, die der Größe des Bildes entspricht, wenn wir es verkleinert oder vergrößert haben.

Vielen Dank!

Hallo,
Es gibt eine Resize()-Funktion in CCanvas.
 
Vitaliy Kuznetsov #:

Cool und nützlich. Nur für Interesse, kann dies in MT4 verwendet werden?

Leider gibt es in MQL4 keine Möglichkeit, eine Ressource als Array anzuhängen. Aber alles andere funktioniert.
Natürlich kann es durch harte Tambourine implementiert werden. Fügen Sie z.B. ein PNG-Bild in eine BMP-Datei ein, d.h. fügen Sie einen BMP-Header am Anfang der png-Datei ein und übergeben Sie die png-Datei selbst als bmp-Bild (d.h. wenn Sie eine solche BMP-Datei öffnen, gibt es ein Rauschen von farbigen Pixeln mit unterschiedlicher Transparenz). Und dann fügen Sie diese "bmp-Datei" als Ressource in MQL4 ein. Dies kann für den Markt notwendig sein, damit ex4 bereits ein Bild in einem dichteren png-Format enthält.
Als Referenz: png ist etwa 10-mal kleiner als das gleiche BMP-Bild ohne Qualitätsverlust, zusätzlich unterstützt volle Transparenz.
Die echte BMP-Ressource in der ex5(ex4)-Datei ist in einem komprimierten Format gespeichert, aber nicht um eine Größenordnung kleiner. Es ist notwendig, genau zu prüfen.
 

Guten Tag an alle. Ich bin auch an diesem Code interessiert. Aber wenn ich Resize() verwende, funktioniert es nicht. Vielleicht sollte es in einer anderen Reihenfolge gemacht werden.

 
Vladimir Nikolaychuk #:

Guten Tag an alle. Ich bin auch an diesem Code interessiert. Aber wenn ich Resize() verwende, funktioniert es nicht. Vielleicht sollte es in einer anderen Reihenfolge gemacht werden.

Okay, ich werde Ihnen später ein Beispiel geben.
Aber ich ziehe es vor, mit einer Leinwand für das gesamte Diagramm zu arbeiten. Das ist in 95 % der Fälle gerechtfertigt.
 
Nikolai Semko #:
Okay, ich werde Ihnen etwas später ein Beispiel geben.
Aber ich ziehe es vor, mit einer Leinwand für das gesamte Diagramm zu arbeiten. Das ist in 95 % der Fälle gerechtfertigt.

Für ein Code-Beispiel wäre ich sehr dankbar. Vielen Dank im Voraus...

 
Nikolai Semko #:
Okay, ich werde Ihnen etwas später ein Beispiel geben.
Aber ich ziehe es vor, mit einer Leinwand für das gesamte Diagramm zu arbeiten. Das ist in 95 % der Fälle gerechtfertigt.

Hier ist ein Beispiel, das auf der png.mql Bibliothek basiert, wenn die Bewegung der Maus die Position des Canvas und seine Größe verändert. Befindet sich der Mauszeiger horizontal in der Mitte, entspricht dies der ursprünglichen Größe des Bildes, nach links - verkleinern, nach rechts - vergrößern.
Ich musste nur die Variablen C und _C in png.mql von privat auf öffentlich umstellen. Sie müssen also diese Bibliothek überschreiben, wenn sie bereits installiert ist.
Dieses Beispiel hat zwei Betriebsarten (Eingabevariable bool resize_canvas):

  • mit Größenänderung des Canvas bei jeder Größenänderung des Bildes
  • ohne Größenänderung von Canvas bei jeder Größenänderung des Bildes. Die anfängliche Größe von Canvas ist gleich der maximal möglichen Bildgröße gemäß der Arbeitslogik.
Leider gibt es im ersten Modus in MQL5 einen uralten Fehler des Bildes blinken, die nur auf eine Weise geheilt werden kann - nicht auf die Leinwand Größe zu ändern. Alle meine Versuche, die Funktion CCanvas.Resize() zu ändern, haben zu nichts geführt. Alles blinkt auf die gleiche Weise. Vielleicht kann ja jemand das Problem lösen :)))
Deshalb ziehe ich es vor, eine Leinwand für den gesamten Bildschirm zu verwenden!

#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.
Dateien: