La tela è forte! - pagina 84

 
Martin Moreno #:
Voglio creare un'interfaccia utente con la classe Canvas. Il mio unico problema è che non so come rendere il cruscotto mobile sul grafico.
Ho cercato molto ma non ho trovato nessun esempio. Vi sarei grato se poteste darmi un suggerimento.


potresti iniziare da questo articolo: 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 #:

potresti iniziare da questo articolo: https: //www.mql5.com/en/articles/12751

Ottimo... Grazie mille!

 
Martin Moreno #:
Voglio creare un'interfaccia utente con la classe Canvas. Il mio unico problema è che non so come rendere il cruscotto mobile sul grafico.
Ho cercato molto ma non ho trovato nessun esempio. Vi sarei grato se poteste darmi un suggerimento.


Ti ho già dato un esempio 4 anni fa :))

Forum sul trading, sui sistemi di trading automatizzati e sul test delle strategie di trading

come convertire tutti gli oggetti in 1 oggetto

Nikolai Semko, 2019.10.05 22:39

In effetti, Canvas è la soluzione.

E Canvas è molto più semplice di quanto sembri a prima vista.

Ecco un esempio primitivo di un indicatore (MQL5 e MQL4) con un oggetto OBJ_BITMAP_LABEL in cui sono presenti molte finestre.

#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 questo nuovo articolo, un'altra opzione per implementare i pannelli informativi.

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

File:
 
Nikolai Semko #:
Qui, ad esempio, ho abbozzato uno script che lo dimostra chiaramente. A destra c'è questo algoritmo veloce e a sinistra il mio (circa 4-10 volte più lento).
.
Nikolai Semko, ciao. In questo esempio https://www.mql5.com/ru/forum/227736/page66#comment_20456641 hai dimostrato il ridimensionamento (rimpicciolimento) dei Bmp.

Posso ridurre l'immagine Bmp, ma la tela rimane della stessa dimensione. Per lo stesso motivo non posso ingrandire l'immagine, che viene ritagliata dalle dimensioni originali, cioè dalle dimensioni della tela.

Non capisco bene gli array, quindi potete spiegarmelo, o meglio mostrarmi un esempio con codice:

1. Ingrandimento dell'immagine

2. Una tela pari alle dimensioni dell'immagine se l'abbiamo ridotta o ingrandita.

Grazie.

 
Vitaliy Kuznetsov #:
Nikolai Semko, ciao. In questo esempio https://www.mql5.com/ru/forum/227736/page66#comment_20456641 hai dimostrato il ridimensionamento (riduzione) dei Bmp.

Posso ridurre l'immagine Bmp, ma la tela rimane della stessa dimensione. Per lo stesso motivo non posso ingrandire l'immagine, che viene ritagliata dalle dimensioni originali, cioè dalle dimensioni della tela.

Non capisco bene gli array, quindi potete spiegarmelo, o meglio mostrarmi un esempio con codice:

1. Ingrandimento dell'immagine

2. Una tela pari alle dimensioni dell'immagine se l'abbiamo ridotta o ingrandita.

Grazie.

Ciao,
Esiste una funzione Resize() in CCanvas.
 
Vitaliy Kuznetsov #:

Bello e utile. Solo per interesse, può essere utilizzato in MT4?

Purtroppo in MQL4 non c'è la possibilità di allegare una risorsa come array. Ma tutto il resto funziona.
Naturalmente, può essere implementato attraverso tamburelli rigidi. Ad esempio, inserire un'immagine PNG in un file BMP, cioè aggiungere un'intestazione BMP all'inizio del png e passare il png stesso come immagine bmp (cioè se si apre un tale BMP, ci sarà un rumore di pixel colorati di diversa trasparenza). E poi allegare questo "file bmp" come risorsa in MQL4. Questo potrebbe essere necessario per il mercato, in modo che ex4 contenga già un'immagine di un formato png più denso.
Per riferimento: il formato png è circa 10 volte più piccolo della stessa immagine BMP senza perdita di qualità, inoltre supporta la trasparenza completa.
La vera risorsa bmp nel file ex5(ex4) è memorizzata in un formato compattato, ma non di un ordine di grandezza inferiore. È necessario verificare esattamente.
 

Buona giornata a tutti. Anche io sono interessato a questo codice. Ma quando uso Resize(), non funziona. Forse dovrebbe essere fatto in una sequenza diversa.

 
Vladimir Nikolaychuk #:

Buona giornata a tutti. Anche io sono interessato a questo codice. Ma quando uso Resize(), non funziona. Forse dovrebbe essere fatto in una sequenza diversa.

Ok, vi darò un esempio più tardi.
Ma preferisco lavorare con un unico canvas per l'intero grafico. È giustificato il 95% delle volte.
 
Nikolai Semko #:
Ok, vi fornirò un esempio poco dopo.
Ma preferisco lavorare con un unico canvas per l'intero grafico. Questo è giustificato il 95% delle volte.

Sarei molto grato per un esempio di codice. Grazie in anticipo...

 
Nikolai Semko #:
Ok, vi fornirò un esempio poco dopo.
Ma preferisco lavorare con un unico canvas per l'intero grafico. Questo è giustificato il 95% delle volte.

Ecco un esempio basato sulla libreria png.mql, in cui il movimento del mouse cambia la posizione del canvas e ne modifica le dimensioni. Se il puntatore del mouse si trova al centro in orizzontale, corrisponde alla dimensione originale dell'immagine, se a sinistra - zoom out, a destra - zoom in.
Solo che ho dovuto riformulare le variabili C e _C in png.mql da private a pubbliche. Quindi è necessario sovrascrivere questa libreria se è già installata.
Questo esempio ha due modalità di funzionamento (variabile di input bool resize_canvas):

  • con il ridimensionamento della tela ogni volta che l'immagine viene ridimensionata
  • senza ridimensionare Canvas ogni volta che l'immagine viene ridimensionata. La dimensione iniziale di Canvas è impostata pari alla dimensione massima possibile dell'immagine secondo la logica di lavoro.
Purtroppo, nella prima modalità di MQL5 c'è un antico bug di lampeggiamento dell'immagine, che può essere curato solo in un modo: non cambiare le dimensioni della tela. Tutti i miei tentativi di modificare la funzione CCanvas.Resize() non hanno portato a nulla. Tutto lampeggia allo stesso modo. Forse qualcuno può farlo :)))
Ecco perché preferisco usare una tela per tutto lo schermo!

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