Обсуждение статьи "Графические интерфейсы X: Сортировка, реконструкция таблицы и элементы управления в ячейках (build 11)" - страница 7

 
Anatoli Kazharski:
В статье наверное не тот пример вставил. В любом случае исправьте под свои задачи, как Вам нужно.

я не занимаюсь передиранием вашего кода, меня интересует работа самого метода SetImages, так нужно, что бы в каждую ячейку заносились рисунки если их используешь в какой либо колонке таблицы, или это ошибка в вашем примере и вставлять нужно только туда, где используешь?
 
Konstantin:

я не занимаюсь передиранием вашего кода, меня интересует работа самого метода SetImages, так нужно, что бы в каждую ячейку заносились рисунки если их используешь в какой либо колонке таблицы, или это ошибка в вашем примере и вставлять нужно только туда, где используешь?

Насколько понял, то Вам нужно, чтобы картинки вставились только в ячейки первого столбца.

Попробуйте вот так:

//+------------------------------------------------------------------+
//| Инициализация таблицы                                            |
//+------------------------------------------------------------------+
void CMainPanel::InitializingTable(void)
  {
//--- Массив названий заголовков
   string text_headers[COLUMNS1_TOTAL]={"Symbol","Bid","Ask","!","Time"};
//--- Массив символов
   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); 
//--- Массив картинок
   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++)
     {
      //--- Установим названия заголовков
      m_canvas_table.SetHeaderText(c,text_headers[c]);
      //---
      for(int r=0; r<ROWS1_TOTAL; r++)
        {
         //--- Установим картинки и названия символов в первый столбец
         if(c<1)
            {
             m_canvas_table.SetImages(c,r,image_array);
             m_canvas_table.SetValue(c,r,text_array[r]);
            }
         //--- Во всех остальных столбцах для всех ячеек значение по умолчанию и без картинок
         else
            m_canvas_table.SetValue(c,r,"-");
        }
     }
  }
 
Anatoli Kazharski:

Насколько понял, то Вам нужно, чтобы картинки вставились только в ячейки первого столбца.

Попробуйте вот так:


))) т.е. все таки опечатка в методе? я примерно таким путем и пошел.

А как поступить лучше в плане оптимизации нагрузки на расчетные мощности. Есть данные которые считаются раз в период (к примеру М5), данные выводим в таблицу из OnTimer. Размер по строкам на каждом пересчете не гарантирован быть равным прошлому расчету. Вижу пока два варианта:
1. После каждого пересчета удаляем все строки и создаем необходимое их количество. В промежутках между пересчетами данные просто обновляются.

2. После каждого пересчета, обновляем данные в имеющиеся строки таблицы, если не хватает строк, то добавляем новые, если строк больше чем данных, то удаляем не нужные.

Какой из данных вариантов приемлем лучше для таблицы на основе CCanvasTable?

 
Konstantin:

...

Какой из данных вариантов приемлем лучше для таблицы на основе CCanvasTable?

Я не смогу так сразу ответить. Попробуйте сделать тесты с замерами по времени (GetTickCount() или GetMicrosecondCount()) или в режиме профилирования протестировать.
 
Anatoli Kazharski:
Я не смогу так сразу ответить. Попробуйте сделать тесты с замерами по времени (GetTickCount() или GetMicrosecondCount()) или в режиме профилирования протестировать.
рисунок вставляется почему то только в колонку с индексом 0, в другие не ставится, это особенность такая или что то не так?
 
Konstantin:
рисунок вставляется почему то только в колонку с индексом 0, в другие не ставится, это особенность такая или что то не так?

А какой результат нужно получить? Подробнее опишите. 

И в чём проблема сделать это самостоятельно? Все необходимые методы ведь для этого предоставлены.

P.S. Показывайте скриншоты и код, чтобы лучше понять, что Вам нужно.

 
Anatoli Kazharski:

А какой результат нужно получить? Подробнее опишите. 

И в чём проблема сделать это самостоятельно? Все необходимые методы ведь для этого предоставлены.

P.S. Показывайте скриншоты и код, чтобы лучше понять, что Вам нужно.


если оттолкнуться на вашем примере, то меняю индекс с 0 на 1:

void CProgram::UpdateTable(void)
  {
   MqlDateTime check_time;
   ::TimeToStruct(::TimeTradeServer(),check_time);
//--- Выйти, если это суббота или воскресенье
   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++)
        {
         //--- Для какого символа получаем данные
         string symbol = m_canvas_table.GetValue(0, r);
         //--- Получаем данные двух последних тиков
         MqlTick ticks[];
         if(::CopyTicks(symbol, ticks, COPY_TICKS_ALL, 0, 2) < 2)
            continue;
         //--- Установить массив, как таймсерии
         ::ArraySetAsSeries(ticks, true);
         //--- Столбец символов - Symbol. Определим направление цены.
         if(c==1)
           {
            int index=0;
            //--- Если цены не изменились
            if(ticks[0].ask==ticks[1].ask && ticks[0].bid==ticks[1].bid)
               index=0;
            //--- Если цена Bid изменилась вверх
            else if(ticks[0].bid>ticks[1].bid)
               index=1;
            //--- Если цена Bid изменилась вниз
            else if(ticks[0].bid<ticks[1].bid)
               index=2;
            //--- Установим соответствующую картинку
            m_canvas_table.ChangeImage(c,r,index,true);
           }
         else
           {
            //--- Столбец разницы цен - Spread (!)
            if(c==3)
              {
               //--- Получим и установим размер спреда в пунктах
               int spread=(int)::SymbolInfoInteger(symbol,SYMBOL_SPREAD);
               m_canvas_table.SetValue(c,r,string(spread),true);
               continue;
              }
            //--- Получим количество знаков после запятой
            int digit=(int)::SymbolInfoInteger(symbol,SYMBOL_DIGITS);
            //--- Столбец цен Bid
            if(c==1)
              {
               m_canvas_table.SetValue(c,r,::DoubleToString(ticks[0].bid,digit));
               //--- Если цена изменилась установим соответствующий направлению цвет
               if(ticks[0].bid!=ticks[1].bid)
                  m_canvas_table.TextColor(c,r,(ticks[0].bid<ticks[1].bid)? clrRed : clrBlue,true);
               //---
               continue;
              }
            //--- Столбец цен Ask
            if(c==2)
              {
               m_canvas_table.SetValue(c,r,::DoubleToString(ticks[0].ask,digit));
               //--- Если цена изменилась установим соответствующий направлению цвет
               if(ticks[0].ask!=ticks[1].ask)
                  m_canvas_table.TextColor(c,r,(ticks[0].ask<ticks[1].ask)? clrRed : clrBlue,true);
               //---
               continue;
              }
            //--- Столбец времени последнего прихода цен символа
            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;
               //--- Если цены не изменились
               if(ticks[0].ask==ticks[1].ask && ticks[0].bid==ticks[1].bid)
                  clr=clrBlack;
               //--- Если цена Bid изменилась вверх
               else if(ticks[0].bid>ticks[1].bid)
                  clr=clrBlue;
               //--- Если цена Bid изменилась вниз
               else if(ticks[0].bid<ticks[1].bid)
                  clr=clrRed;
               //--- Установим значение и цвет текста
               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);

//--- Обновить таблицу
   m_canvas_table.UpdateTable();
  }

значки должны переместиться в колонку с индексом 1, т.е. вторая, но этого не происходит. Пример взят из TestLibrary10.mqh. Каких либо методов позиционирующих рисунки не нашел, если есть подскажите.

 
Вообще не могу понять принцип загрузки рисунков в ячейки таблицы. В примере TestLibrary09.mqh рисунки грузятся в разные колонки, а в примере TestLibrary10.mqh только в колонку с индексом 0, при установке в другие колонки рисунки не грузятся. Подскажите в чем там тонкость?
 
Konstantin:
Вообще не могу понять принцип загрузки рисунков в ячейки таблицы. В примере TestLibrary09.mqh рисунки грузятся в разные колонки, а в примере TestLibrary10.mqh только в колонку с индексом 0, при установке в другие колонки рисунки не грузятся. Подскажите в чем там тонкость?

Для каждой ячейки таблицы, в которой должны быть картинки, нужен свой массив картинок. Если ячейка с типом CELL_BUTTON, то достаточно минимум одной картинки на ячейку, если тип CELL_CHECKBOX, то минимум две.

Наприме:

Картинка с индексом 0 - соответствует "отжатому" состоянию чекбокса (кнопки), остальные индексы соответствуют "выбранному" состоянию чекбокса (кнопки).

(не доделано, но для понимания пойдёт):

В правой таблице со списком символов есть лишь один столбец, и он имеет тип CELL_CHECKBOX - для него необходим размер массива изображений минимум 2:
arr_chk[2]; arr_chk[0]=m_img_chk_off; (изображение чекбокса со снятой галочкой) arr_chk[1]=m_img_chk_on; (изображение чекбокса с установленной галочкой)


В основной таблице:

Ячейка 0 содержит картинку открытия графика - у неё тип CELL_BUTTON, массив изображений можно иметь с размерностью 1: arr_img0[1]; arr_img0[0]=m_image_graph;

Ячейка 8 содержит картинку открытия Buy - у неё тип CELL_BUTTON, массив изображений можно иметь с размерностью 1: arr_img8[1]; arr_img8[0]=m_image_buy;

Ячейка 9 содержит картинку открытия Sell - у неё тип CELL_BUTTON, массив изображений можно иметь с размерностью 1: arr_img9[1]; arr_img9[0]=m_image_sell;

После создания таблицы можно инициализировать её нужными значениями и установить нужные типы ячеек и задать для них свои массивы изображений.


 
Artyom Trishkin:

Для каждой ячейки таблицы, в которой должны быть картинки, нужен свой массив картинок. Если ячейка с типом CELL_BUTTON, то достаточно минимум одной картинки на ячейку, если тип CELL_CHECKBOX, то минимум две. Картинка с индексом 0 - соответствует "отжатому" состоянию чекбокса (кнопки), остальные индексы соответствуют "выбранному" состоянию чекбокса (кнопки).

Например (не доделано, но для понимания пойдёт):

В правой таблице со списком символов есть лишь один столбец, и он имеет тип CELL_CHECKBOX - для него необходим размер массива изображений минимум 2:
arr_chk[2]; arr_chk[0]=m_img_chk0; arr_chk[1]=m_img_chk1;


В основной таблице:

Ячейка 0 содержит картинку открытия графика - у неё тип CELL_BUTTON, массив изображений можно иметь с размерностью 1: arr_img0[1]; arr_img0[0]=m_image_graph;

Ячейка 8 содержит картинку открытия Buy - у неё тип CELL_BUTTON, массив изображений можно иметь с размерностью 1: arr_img8[1]; arr_img8[0]=m_image_buy;

Ячейка 9 содержит картинку открытия Sell - у неё тип CELL_BUTTON, массив изображений можно иметь с размерностью 1: arr_img9[1]; arr_img9[0]=m_image_sell;

После создания таблицы можно инициализировать её нужными значениями и установить нужные типы ячеек и задать для них свои массивы изображений.


Я реально не понимаю в чем проблема )) в первом скрине изменил на колонку с индексом 1 рисунки исчезли, а во втором скрине обратно вернул на колонку с индексом 0, рисунки появились. Это все на примере кода TestLibrary10.mqh 

Вот методы создания таблицы:

bool CProgram::CreateCanvasTable(const int x_gap,const int y_gap)
  {
#define COLUMNS1_TOTAL 5
#define ROWS1_TOTAL    27
//--- Сохраним указатель на форму
   m_canvas_table.WindowPointer(m_window);
//--- Массив ширины столбцов
   int width[COLUMNS1_TOTAL]={75, 60, 60, 60, 75};
//--- Массив отступа текста в столбцах по оси X
   int text_x_offset[COLUMNS1_TOTAL];
   ::ArrayInitialize(text_x_offset,5);
   text_x_offset[0]=25;
//--- Массив выравнивания текста в столбцах
   ENUM_ALIGN_MODE align[COLUMNS1_TOTAL];
   ::ArrayInitialize(align,ALIGN_RIGHT);
   align[0]=ALIGN_LEFT;
//--- Установим свойства перед созданием
   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);
//--- Заполним таблицу данными
   InitializingTable();
//--- Создадим элемент управления
   if(!m_canvas_table.CreateTable(m_chart_id,m_subwin,x_gap,y_gap))
      return(false);
//--- Добавим объект в общий массив групп объектов
   CWndContainer::AddToElementsArray(0,m_canvas_table);
   return(true);
  }

это инициализация:

void CProgram::InitializingTable(void)
  {
//--- Массив названий заголовков
   string text_headers[COLUMNS1_TOTAL]={"Symbol","Bid","Ask","!","Time"};
//--- Массив символов
   //string 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); 
//--- Массив картинок
   string image_array[3]=
     {
      "::Images\\EasyAndFastGUI\\Icons\\bmp16\\circle_gray.bmp",//circle_gray_t32.bmp",
      "::Images\\EasyAndFastGUI\\Icons\\bmp16\\arrow_up.bmp",
      "::Images\\EasyAndFastGUI\\Icons\\bmp16\\arrow_down.bmp"
     };
//---
   for(int c=0; c<COLUMNS1_TOTAL; c++)
     {
      //--- Установим названия заголовков
      m_canvas_table.SetHeaderText(c,text_headers[c]);
      //---
      for(int r=0; r<ROWS1_TOTAL; r++)
        {
         //--- Установим картинки
         if(c == 1) {
            m_canvas_table.CellType(c, r, CELL_BUTTON);
            m_canvas_table.SetImages(c,r,image_array);
         }
         //--- Установим названия символов
         if(c<1)
            m_canvas_table.SetValue(c,r,text_array[r]);
         //--- Для всех ячеек значение по умолчанию
         else
            m_canvas_table.SetValue(c,r,"-");
        }
     }
  }

это обновление:

void CProgram::UpdateTable(void)
  {
   MqlDateTime check_time;
   ::TimeToStruct(::TimeTradeServer(),check_time);
//--- Выйти, если это суббота или воскресенье
   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++)
        {
         //--- Для какого символа получаем данные
         string symbol = m_canvas_table.GetValue(0, r);
         //--- Получаем данные двух последних тиков
         MqlTick ticks[];
         if(::CopyTicks(symbol, ticks, COPY_TICKS_ALL, 0, 2) < 2)
            continue;
         //--- Установить массив, как таймсерии
         ::ArraySetAsSeries(ticks, true);
         //--- Столбец символов - Symbol. Определим направление цены.
         if(c==1)
           {
            int index=0;
            //--- Если цены не изменились
            if(ticks[0].ask==ticks[1].ask && ticks[0].bid==ticks[1].bid)
               index=0;
            //--- Если цена Bid изменилась вверх
            else if(ticks[0].bid > ticks[1].bid)
               index=1;
            //--- Если цена Bid изменилась вниз
            else if(ticks[0].bid < ticks[1].bid)
               index=2;
            //--- Установим соответствующую картинку
            m_canvas_table.ChangeImage(c,r,index,true);
           }
         else
           {
            //--- Столбец разницы цен - Spread (!)
            if(c==3)
              {
               //--- Получим и установим размер спреда в пунктах
               int spread=(int)::SymbolInfoInteger(symbol,SYMBOL_SPREAD);
               m_canvas_table.SetValue(c,r,string(spread),true);
               continue;
              }
            //--- Получим количество знаков после запятой
            int digit=(int)::SymbolInfoInteger(symbol,SYMBOL_DIGITS);
            //--- Столбец цен Bid
            if(c==1)
              {
               m_canvas_table.SetValue(c,r,::DoubleToString(ticks[0].bid,digit));
               //--- Если цена изменилась установим соответствующий направлению цвет
               if(ticks[0].bid!=ticks[1].bid)
                  m_canvas_table.TextColor(c,r,(ticks[0].bid<ticks[1].bid)? clrRed : clrBlue,true);
               //---
               continue;
              }
            //--- Столбец цен Ask
            if(c==2)
              {
               m_canvas_table.SetValue(c,r,::DoubleToString(ticks[0].ask,digit));
               //--- Если цена изменилась установим соответствующий направлению цвет
               if(ticks[0].ask!=ticks[1].ask)
                  m_canvas_table.TextColor(c,r,(ticks[0].ask<ticks[1].ask)? clrRed : clrBlue,true);
               //---
               continue;
              }
            //--- Столбец времени последнего прихода цен символа
            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;
               //--- Если цены не изменились
               if(ticks[0].ask==ticks[1].ask && ticks[0].bid==ticks[1].bid)
                  clr=clrBlack;
               //--- Если цена Bid изменилась вверх
               else if(ticks[0].bid>ticks[1].bid)
                  clr=clrBlue;
               //--- Если цена Bid изменилась вниз
               else if(ticks[0].bid<ticks[1].bid)
                  clr=clrRed;
               //--- Установим значение и цвет текста
               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);

//--- Обновить таблицу
   m_canvas_table.UpdateTable();
  }
выделенное заменил с 0 на 1, т.е. изменил вставку картинки в колонку с номера 0 на номер 1, где тут ошибка?
Файлы:
07.png  163 kb
00.png  161 kb
Причина обращения: