Discusión sobre el artículo "Interfaces gráficas X: Ordenamiento, reconstrucción de la tabla y controles en las celdas (build 11)" - página 7

 
Anatoli Kazharski:
Debo haber insertado el ejemplo equivocado en el artículo. En cualquier caso, corrígelo para tus tareas como necesites.

No estoy copiando tu código, me interesa el trabajo del propio método SetImages, ¿es necesario poner imágenes en cada celda si las usas en cualquier columna de la tabla, o es un error de tu ejemplo y necesitas insertarlas sólo donde las usas?
 
Konstantin:

No estoy copiando tu código, me interesa el trabajo del propio método SetImages, ¿es necesario poner imágenes en cada celda si las usas en cualquier columna de la tabla, o es un error de tu ejemplo y sólo debes insertarlas donde las uses?

Por lo que tengo entendido, es necesario insertar imágenes sólo en las celdas de la primera columna.

Pruébalo así:

//+------------------------------------------------------------------+
//| Inicialización de la tabla|
//+------------------------------------------------------------------+
void CMainPanel::InitializingTable(void)
  {
//--- Matriz de nombres de cabecera
   string text_headers[COLUMNS1_TOTAL]={"Symbol","Bid","Ask","!","Time"};
//--- Matriz de caracteres
   string text_str = "MFON SBER SBERP GAZP TATN LKOH ROSN NVTK SNGS SNGSP VTBR MOEX AFKS IRAO "
                     "AFLT FEES ALRS MAGN NLMK CHMF GMKN HYDR TATNP YNDX RTKM MGNT MTSS";
   string text_array[];
   int _size = CreateArray(text_str, text_array); 
//--- Matriz de imágenes
   string image_array[3]=
     {
      "::Images\\EasyAndFastGUI\\Icons\\bmp16\\circle_gray.bmp",
      "::Images\\EasyAndFastGUI\\Icons\\bmp16\\arrow_up.bmp",
      "::Images\\EasyAndFastGUI\\Icons\\bmp16\\arrow_down.bmp"
     };
//---
   for(int c=0; c<COLUMNS1_TOTAL; c++)
     {
      //--- Establecer los nombres de cabecera
      m_canvas_table.SetHeaderText(c,text_headers[c]);
      //---
      for(int r=0; r<ROWS1_TOTAL; r++)
        {
         //--- Poner imágenes y nombres de personajes en la primera columna
         if(c<1)
            {
             m_canvas_table.SetImages(c,r,image_array);
             m_canvas_table.SetValue(c,r,text_array[r]);
            }
         //--- En todas las demás columnas para todas las celdas el valor por defecto y sin imágenes
         else
            m_canvas_table.SetValue(c,r,"-");
        }
     }
  }
 
Anatoli Kazharski:

Por lo que tengo entendido, necesitas insertar imágenes sólo en las celdas de la primera columna.

Prueba con esto:


))))) así que todavía hay un error tipográfico en el método? Yo lo hice de esta manera.

Y cuál es la mejor manera de optimizar la carga de las capacidades calculadas. Hay datos que se cuentan una vez por período (por ejemplo, M5), los datos se muestran en una tabla de OnTimer. No se garantiza que el tamaño de las filas en cada recálculo sea igual al último cálculo. Hasta ahora veo dos opciones:
1. Después de cada recálculo borrar todas las filas y crear el número necesario de filas. Entre recálculo y recálculo simplemente se actualizan los datos.

2. Después de cada recálculo, actualizamos los datos en las filas existentes de la tabla, si no hay suficientes filas, añadimos nuevas, si hay más filas que datos, borramos las que no necesitamos.

¿Cuál de estas opciones es más aceptable para una tabla basada en CCanvasTable?

 
Konstantin:

...

¿Cuál de estas opciones es más aceptable para una tabla basada en CCanvasTable?

No podré responder a eso de inmediato. Intenta hacer pruebas con medidas de tiempo(GetTickCount() o GetMicrosecondCount()) o prueba en modo profiling.
 
Anatoli Kazharski:
No podré darte una respuesta inmediata. Intenta hacer pruebas con medidas de tiempo(GetTickCount() o GetMicrosecondCount()) o prueba en modo profiling.
por alguna razón la imagen se inserta sólo en la columna con índice 0, no se inserta en otras columnas, ¿es una peculiaridad o algo está mal?
 
Konstantin:
por alguna razón la imagen se inserta sólo en la columna con índice 0, en otras columnas no se pone, ¿es una peculiaridad o algo mal?

¿Y qué resultado quieres obtener? Describe detalladamente.

¿Y cuál es el problema para hacerlo tú mismo? Para eso están todos los métodos necesarios.

P.D. Muestra capturas de pantalla y código para entender mejor lo que necesitas.

 
Anatoli Kazharski:

¿Y qué resultado desea? Descríbelo con detalle.

¿Y qué problema hay en hacerlo uno mismo? Se proporcionan todos los métodos necesarios para ello.

P.D. Muestra capturas de pantalla y código para entender mejor lo que necesitas.


Si uso tu ejemplo, cambio el índice de 0 a 1:

void CProgram::UpdateTable(void)
  {
   MqlDateTime check_time;
   ::TimeToStruct(::TimeTradeServer(),check_time);
//--- Salir si es sábado o domingo
   if(check_time.day_of_week==0 || check_time.day_of_week==6)
      return;
//---
   for(uint c=0; c < m_canvas_table.ColumnsTotal(); c++)
     {
      for(uint r=0; r < m_canvas_table.RowsTotal(); r++)
        {
         //--- Para qué carácter obtenemos datos
         string symbol = m_canvas_table.GetValue(0, r);
         //--- Obtener los datos de los dos últimos ticks
         MqlTick ticks[];
         if(::CopyTicks(symbol, ticks, COPY_TICKS_ALL, 0, 2) < 2)
            continue;
         //--- Establecer la matriz como una serie de tiempo
         ::ArraySetAsSeries(ticks, true);
         //--- Columna de símbolos - Símbolo. Determinemos la dirección del precio.
         if(c==1)
           {
            int index=0;
            //--- Si los precios no han cambiado
            if(ticks[0].ask==ticks[1].ask && ticks[0].bid==ticks[1].bid)
               index=0;
            //--- Si el precio de oferta ha cambiado al alza
            else if(ticks[0].bid>ticks[1].bid)
               index=1;
            //--- Si el precio de oferta ha cambiado a la baja
            else if(ticks[0].bid<ticks[1].bid)
               index=2;
            //--- Establecer la imagen correspondiente
            m_canvas_table.ChangeImage(c,r,index,true);
           }
         else
           {
            //--- Columna de diferencia de precio - Spread (!)
            if(c==3)
              {
               //--- Obtener y establecer el tamaño del spread en pips
               int spread=(int)::SymbolInfoInteger(symbol,SYMBOL_SPREAD);
               m_canvas_table.SetValue(c,r,string(spread),true);
               continue;
              }
            //--- Obtener el número de decimales
            int digit=(int)::SymbolInfoInteger(symbol,SYMBOL_DIGITS);
            //--- Columna Precio Oferta
            if(c==1)
              {
               m_canvas_table.SetValue(c,r,::DoubleToString(ticks[0].bid,digit));
               //--- Si el precio ha cambiado, establece el color correspondiente a la dirección
               if(ticks[0].bid!=ticks[1].bid)
                  m_canvas_table.TextColor(c,r,(ticks[0].bid<ticks[1].bid)? clrRed : clrBlue,true);
               //---
               continue;
              }
            //--- Columna precio de venta
            if(c==2)
              {
               m_canvas_table.SetValue(c,r,::DoubleToString(ticks[0].ask,digit));
               //--- Si el precio ha cambiado, establece el color correspondiente a la dirección
               if(ticks[0].ask!=ticks[1].ask)
                  m_canvas_table.TextColor(c,r,(ticks[0].ask<ticks[1].ask)? clrRed : clrBlue,true);
               //---
               continue;
              }
            //--- Columna de la última hora de llegada de los precios de los símbolos
            if(c==4)
              {
               long   time     =::SymbolInfoInteger(symbol,SYMBOL_TIME);
               string time_msc =::IntegerToString(ticks[0].time_msc);
               int    length   =::StringLen(time_msc);
               string msc      =::StringSubstr(time_msc,length-3,3);
               string str      =::TimeToString(time,TIME_MINUTES|TIME_SECONDS)+"."+msc;
               //---
               color clr=clrBlack;
               //--- Si los precios no han cambiado
               if(ticks[0].ask==ticks[1].ask && ticks[0].bid==ticks[1].bid)
                  clr=clrBlack;
               //--- Si el precio de oferta ha cambiado al alza
               else if(ticks[0].bid>ticks[1].bid)
                  clr=clrBlue;
               //--- Si el precio de oferta ha cambiado a la baja
               else if(ticks[0].bid<ticks[1].bid)
                  clr=clrRed;
               //--- Establecer el valor y el color del texto
               m_canvas_table.SetValue(c,r,str);
               m_canvas_table.TextColor(c,r,clr,true);
               continue;
              }
           }
        }
     }

   int _height = int(m_chart.HeightInPixels(0) * .30);
   m_canvas_table.AutoYResizeBottomOffset(_height);

//--- Actualizar tabla
   m_canvas_table.UpdateTable();
  }

los iconos deberían moverse a la columna con índice 1, es decir, la segunda, pero no ocurre. El ejemplo está tomado de TestLibrary10.mqh. No he encontrado ningún método para posicionar las figuras, si hay alguno, por favor decídmelo.

 
En general, no puedo entender el principio de la carga de dibujos en las celdas de la tabla. En el ejemplo TestLibrary09.mqh dibujos se cargan en diferentes columnas, y en el ejemplo TestLibrary10.mqh sólo en la columna con el índice 0, cuando se establece en otras columnas dibujos no se cargan. ¿Me puede decir cuál es la sutileza allí?
 
Konstantin:
En general, no puedo entender el principio de la carga de dibujos en las celdas de la tabla. En el ejemplo TestLibrary09.mqh dibujos se cargan en diferentes columnas, y en el ejemplo TestLibrary10.mqh sólo en la columna con el índice 0, cuando se establece en otras columnas dibujos no se cargan. ¿Puede decirme cuál es la sutileza allí?

Para cada celda de la tabla, que debe ser imágenes, necesita su propia matriz de imágenes. Si la celda con el tipo CELL_BUTTON, a continuación, un mínimo de una imagen por celda es suficiente, si el tipo CELL_CHECKBOX, a continuación, un mínimo de dos.

Por ejemplo:

La imagen con índice 0 - corresponde al estado "pulsado" de la casilla de verificación (botón), los otros índices corresponden al estado "seleccionado" de la casilla de verificación (botón).

(no está terminado, pero servirá para entenderlo):

En la tabla derecha sólo hay una columna con la lista de símbolos, y es de tipo CELL_CHECKBOX - requiere un tamaño de array de imágenes de al menos 2:
arr_chk[2]; arr_chk[0]=m_img_chk_off; (imagen de una casilla de verificación con la casilla desmarcada) arr_chk[1]=m_img_chk_on; (imagen de una casilla de verificación con la casilla marcada)


En la tabla principal:

La celda 0 contiene la imagen de apertura del gráfico - tiene tipo CELL_BUTTON, puede tener un array de imágenes con dimensión 1: arr_img0[1]; arr_img0[0]=m_image_graph;

La celda 8 contiene la imagen de apertura Comprar - su tipo es CELL_BUTTON, el array de imágenes puede ser de dimensión 1: arr_img8[1]; arr_img8[0]=m_image_buy;

La celda 9 contiene la imagen de apertura de la venta - tiene el tipo CELL_BUTTON, la matriz de imágenes puede ser de dimensión 1: arr_img9[1]; arr_img9[0]=m_image_sell;

Después de crear la tabla, puede inicializarla con los valores requeridos y establecer los tipos de celda requeridos y establecer sus propias matrices de imágenes para ellos.


 
Artyom Trishkin:

Para cada celda de la tabla, que debe contener imágenes, se necesita su propia matriz de imágenes. Si la celda es de tipo CELL_BUTTON, entonces es suficiente con un mínimo de una imagen por celda, si el tipo es CELL_CHECKBOX, entonces un mínimo de dos. La imagen con índice 0 corresponde al estado "pulsado" de la casilla de verificación (botón), los otros índices corresponden al estado "seleccionado" de la casilla de verificación (botón).

Por ejemplo (no está terminado, pero servirá para entenderlo):

En la tabla de la derecha con la lista de símbolos, sólo hay una columna, y es de tipo CELL_CHECKBOX - requiere un tamaño de array de imágenes de al menos 2:
arr_chk[2]; arr_chk[0]=m_img_chk0; arr_chk[1]=m_img_chk1;


En la tabla principal:

La celda 0 contiene la imagen de apertura del gráfico - tiene tipo CELL_BUTTON, puede tener un array de imágenes con dimensión 1: arr_img0[1]; arr_img0[0]=m_image_graph;

La celda 8 contiene la imagen de apertura Comprar - su tipo es CELL_BUTTON, el array de imágenes puede ser de dimensión 1: arr_img8[1]; arr_img8[0]=m_image_buy;

La celda 9 contiene la imagen de apertura de la venta - tiene el tipo CELL_BUTTON, la matriz de imágenes puede ser de dimensión 1: arr_img9[1]; arr_img9[0]=m_image_sell;

Una vez creada la tabla, se puede inicializar con los valores deseados y establecer los tipos de celda deseados y establecer sus matrices de imágenes para ellos.


Realmente no entiendo cual es el problema )) en la primera pantalla al cambiar a la columna con índice 1 las imágenes desaparecían, y en la segunda pantalla al volver a la columna con índice 0, las imágenes aparecían. Todo esto es en el código de ejemplo TestLibrary10. mqh

Estos son los métodos de creación de la tabla

bool CProgram::CreateCanvasTable(const int x_gap,const int y_gap)
  {
#define  COLUMNS1_TOTAL 5
#define  ROWS1_TOTAL    27
//--- Guardar el puntero al formulario
   m_canvas_table.WindowPointer(m_window);
//--- Matriz de anchos de columna
   int width[COLUMNS1_TOTAL]={75, 60, 60, 60, 75};
//--- Matriz de la sangría del texto en columnas en el eje X
   int text_x_offset[COLUMNS1_TOTAL];
   ::ArrayInitialize(text_x_offset,5);
   text_x_offset[0]=25;
//--- Array de alineación de texto en columnas
   ENUM_ALIGN_MODE align[COLUMNS1_TOTAL];
   ::ArrayInitialize(align,ALIGN_RIGHT);
   align[0]=ALIGN_LEFT;
//--- Establecer propiedades antes de la creación
   m_canvas_table.XSize(345);
   m_canvas_table.YSize(289);
   m_canvas_table.TableSize(COLUMNS1_TOTAL, ROWS1_TOTAL);
   m_canvas_table.TextAlign(align);
   m_canvas_table.TextXOffset(text_x_offset);
   m_canvas_table.ColumnsWidth(width);
   m_canvas_table.TextXOffset(5);
   m_canvas_table.TextYOffset(4);
   m_canvas_table.CellYSize(20);
   //m_canvas_table.ImageXOffset(8);//
   //m_canvas_table.ImageYOffset(6);//
   m_canvas_table.ShowHeaders(true);
   m_canvas_table.HeaderYSize(30);
   m_canvas_table.HeadersColor(C'255,244,213');
   m_canvas_table.CellColorHover(C'255,244,213');
   m_canvas_table.LightsHover(true);
   m_canvas_table.SelectableRow(true);
   m_canvas_table.ColumnResizeMode(true);
   m_canvas_table.IsZebraFormatRows(clrWhiteSmoke);
   //m_canvas_table.AutoXResizeMode(true);
   m_canvas_table.AutoXResizeRightOffset(1);
   m_canvas_table.AutoYResizeMode(true);
   int _height = int(m_chart.HeightInPixels(0) * .30);
   m_canvas_table.AutoYResizeBottomOffset(/*25 + */_height);
//--- Rellenar la tabla con datos
   InitializingTable();
//--- Crear un control
   if(!m_canvas_table.CreateTable(m_chart_id,m_subwin,x_gap,y_gap))
      return(false);
//--- Añade el objeto al array común de grupos de objetos
   CWndContainer::AddToElementsArray(0,m_canvas_table);
   return(true);
  }

es inicialización:

void CProgram::InitializingTable(void)
  {
//--- Matriz de nombres de cabecera
   string text_headers[COLUMNS1_TOTAL]={"Symbol","Bid","Ask","!","Time"};
//--- Matriz de caracteres
   //serie text_array[25]=
   // {
   // "AUDUSD", "GBPUSD", "EURUSD", "USDCAD", "USDCHF", "USDJPY", "NZDUSD", "USDSEK", "USDHKD", "USDMXN",
   // "USDZAR", "USDTRY", "GBPAUD", "AUDCAD", "CADCHF", "EURAUD", "GBPCHF", "GBPJPY", "NZDJPY", "AUDJPY",
   // "EURJPY", "EURCHF", "EURGBP", "AUDCHF", "CHFJPY"
   // };
   string text_str = "MFON SBER SBERP GAZP TATN LKOH ROSN NVTK SNGS SNGSP VTBR MOEX AFKS IRAO "
                     "AFLT FEES ALRS MAGN NLMK CHMF GMKN HYDR TATNP YNDX RTKM MGNT MTSS";
   string text_array[];
   int _size = CreateArray(text_str, text_array); 
//--- Matriz de imágenes
   string image_array[3]=
     {
      "::Images\\EasyAndFastGUI\\Icons\\bmp16\\circle_gray.bmp",//circulo_gris_t32.bmp",
      "::Images\\EasyAndFastGUI\\Icons\\bmp16\\arrow_up.bmp",
      "::Images\\EasyAndFastGUI\\Icons\\bmp16\\arrow_down.bmp"
     };
//---
   for(int c=0; c<COLUMNS1_TOTAL; c++)
     {
      //--- Establecer los nombres de cabecera
      m_canvas_table.SetHeaderText(c,text_headers[c]);
      //---
      for(int r=0; r<ROWS1_TOTAL; r++)
        {
         //--- Establecer las imágenes
         if(c == 1) {
            m_canvas_table.CellType(c, r, CELL_BUTTON);
            m_canvas_table.SetImages(c,r,image_array);
         }
         //--- Establecer nombres de caracteres
         if(c<1)
            m_canvas_table.SetValue(c,r,text_array[r]);
         //--- Valor por defecto para todas las celdas
         else
            m_canvas_table.SetValue(c,r,"-");
        }
     }
  }

es actualización:

void CProgram::UpdateTable(void)
  {
   MqlDateTime check_time;
   ::TimeToStruct(::TimeTradeServer(),check_time);
//--- Salir si es sábado o domingo
   if(check_time.day_of_week==0 || check_time.day_of_week==6)
      return;
//---
   for(uint c=0; c < m_canvas_table.ColumnsTotal(); c++)
     {
      for(uint r=0; r < m_canvas_table.RowsTotal(); r++)
        {
         //--- Para qué carácter obtenemos datos
         string symbol = m_canvas_table.GetValue(0, r);
         //--- Obtener los datos de los dos últimos ticks
         MqlTick ticks[];
         if(::CopyTicks(symbol, ticks, COPY_TICKS_ALL, 0, 2) < 2)
            continue;
         //--- Establecer la matriz como una serie de tiempo
         ::ArraySetAsSeries(ticks, true);
         //--- Columna de símbolos - Símbolo. Determinemos la dirección del precio.
         if(c==1)
           {
            int index=0;
            //--- Si los precios no han cambiado
            if(ticks[0].ask==ticks[1].ask && ticks[0].bid==ticks[1].bid)
               index=0;
            //--- Si el precio de oferta ha cambiado al alza
            else if(ticks[0].bid > ticks[1].bid)
               index=1;
            //--- Si el precio de oferta ha cambiado a la baja
            else if(ticks[0].bid < ticks[1].bid)
               index=2;
            //--- Establecer la imagen correspondiente
            m_canvas_table.ChangeImage(c,r,index,true);
           }
         else
           {
            //--- Columna de diferencia de precio - Spread (!)
            if(c==3)
              {
               //--- Obtener y establecer el tamaño del spread en pips
               int spread=(int)::SymbolInfoInteger(symbol,SYMBOL_SPREAD);
               m_canvas_table.SetValue(c,r,string(spread),true);
               continue;
              }
            //--- Obtener el número de decimales
            int digit=(int)::SymbolInfoInteger(symbol,SYMBOL_DIGITS);
            //--- Columna Precio Oferta
            if(c==1)
              {
               m_canvas_table.SetValue(c,r,::DoubleToString(ticks[0].bid,digit));
               //--- Si el precio ha cambiado, establece el color correspondiente a la dirección
               if(ticks[0].bid!=ticks[1].bid)
                  m_canvas_table.TextColor(c,r,(ticks[0].bid<ticks[1].bid)? clrRed : clrBlue,true);
               //---
               continue;
              }
            //--- Columna precio de venta
            if(c==2)
              {
               m_canvas_table.SetValue(c,r,::DoubleToString(ticks[0].ask,digit));
               //--- Si el precio ha cambiado, establece el color correspondiente a la dirección
               if(ticks[0].ask!=ticks[1].ask)
                  m_canvas_table.TextColor(c,r,(ticks[0].ask<ticks[1].ask)? clrRed : clrBlue,true);
               //---
               continue;
              }
            //--- Columna de la última hora de llegada de los precios de los símbolos
            if(c==4)
              {
               long   time     =::SymbolInfoInteger(symbol,SYMBOL_TIME);
               string time_msc =::IntegerToString(ticks[0].time_msc);
               int    length   =::StringLen(time_msc);
               string msc      =::StringSubstr(time_msc,length-3,3);
               string str      =::TimeToString(time,TIME_MINUTES|TIME_SECONDS)+"."+msc;
               //---
               color clr=clrBlack;
               //--- Si los precios no han cambiado
               if(ticks[0].ask==ticks[1].ask && ticks[0].bid==ticks[1].bid)
                  clr=clrBlack;
               //--- Si el precio de oferta ha cambiado al alza
               else if(ticks[0].bid>ticks[1].bid)
                  clr=clrBlue;
               //--- Si el precio de oferta ha cambiado a la baja
               else if(ticks[0].bid<ticks[1].bid)
                  clr=clrRed;
               //--- Establecer el valor y el color del texto
               m_canvas_table.SetValue(c,r,str);
               m_canvas_table.TextColor(c,r,clr,true);
               continue;
              }
           }
        }
     }

   int _height = int(m_chart.HeightInPixels(0) * .30);
   m_canvas_table.AutoYResizeBottomOffset(_height);

//--- Actualizar tabla
   m_canvas_table.UpdateTable();
  }
destacó cambiado de 0 a 1, es decir, cambió la inserción de imágenes en la columna del número 0 al número 1, ¿dónde está el error aquí?
Archivos adjuntos:
07.png  163 kb
00.png  161 kb