記事"グラフィカルインターフェイスX:ソート、テーブル再構築とセル内のコントロール(ビルド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:

私の理解では、最初の列のセルにのみ画像を挿入する必要があります。

試してみてください:


))))))))))) まだ、メソッドにタイプミスがあるのですか? 私はこのようにしました。

また、計算された容量の負荷を最適化する最善の方法は何でしょうか。ある期間(例えばM5)に1回カウントされるデータがあり、そのデータは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);
         //--- 直近2ティックのデータを取得する
         MqlTick ticks[];
         if(::CopyTicks(symbol, ticks, COPY_TICKS_ALL, 0, 2) < 2)
            continue;
         //--- 配列を時系列として設定する
         ::ArraySetAsSeries(ticks, true);
         //--- シンボル欄 - シンボル。価格の方向を決定しよう。
         if(c==1)
           {
            int index=0;
            //--- 価格が変わっていない場合
            if(ticks[0].ask==ticks[1].ask && ticks[0].bid==ticks[1].bid)
               index=0;
            //--- ビッド価格が上方修正された場合
            else if(ticks[0].bid>ticks[1].bid)
               index=1;
            //--- ビッド価格が下方に変動した場合
            else if(ticks[0].bid<ticks[1].bid)
               index=2;
            //--- 対応する画像を設定する
            m_canvas_table.ChangeImage(c,r,index,true);
           }
         else
           {
            //--- 価格差欄 - スプレッド(!)
            if(c==3)
              {
               //--- スプレッドの大きさをpips単位で取得・設定する。
               int spread=(int)::SymbolInfoInteger(symbol,SYMBOL_SPREAD);
               m_canvas_table.SetValue(c,r,string(spread),true);
               continue;
              }
            //--- 小数点の桁数を取得する
            int digit=(int)::SymbolInfoInteger(symbol,SYMBOL_DIGITS);
            //--- 価格欄 入札
            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;
              }
            //--- 売値欄
            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;
               //--- ビッド価格が上方修正された場合
               else if(ticks[0].bid>ticks[1].bid)
                  clr=clrBlue;
               //--- ビッド価格が下方に変動した場合
               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の列、つまり2番目の列に移動するはずですが、そうはなりません。この例はTestLibrary10.mqhから 引用しています。もしあれば教えてください。

 
一般的に、テーブルのセルに 絵を読み込む原理が理解できません。TestLibrary09.mqhの 例では、異なるカラムに図面が読み込まれ、TestLibrary10.mqhの 例では、インデックス0のカラムにのみ読み込まれ、他のカラムに設定された図面は読み込まれません。何が微妙なのか教えてください。
 
Konstantin:
一般的に、テーブルのセルに絵を読み込む原理が理解できません。TestLibrary09.mqhの 例では、異なるカラムに図面が読み込まれ、TestLibrary10.mqhの 例では、インデックス0のカラムにのみ読み込まれ、他のカラムに設定された図面は読み込まれません。何が微妙なのか教えてください。

テーブルの各セルには絵が必要ですが、それには絵の配列が必要です。CELL_BUTTON型のセルであれば、セルごとに最低1枚の絵があれば十分ですし、CELL_CHECKBOX型であれば、最低2枚の絵があれば十分です。

例えば

インデックス0の画像はチェックボックス(ボタン)の "押された "状態に対応し、他のインデックスはチェックボックス(ボタン)の "選択された "状態に対応します。

(完成ではありませんが、理解のためにはこれで十分です):


arr_chk[2]; arr_chk[0]=m_img_chk_off; (チェックボックスがチェックされていない状態のチェックボックスの画像) arr_chk[1]=m_img_chk_on; (チェックボックスがチェックされている状態のチェックボックスの画像)。


メイン・テーブル:

セル0には、グラフのオープニング画像が格納されます。セルタイプはCELL_BUTTONで、1次元の画像配列を持つことができます;

セル8は買いのオープニング画像で、タイプはCELL_BUTTON、画像配列は1次元です: arr_img8[1]; arr_img8[0]=m_image_buy;

セル9には、セルのオープニング画像が格納されています;

テーブルを作成した後、必要な値で初期化し、必要なセル・タイプを設定し、独自の画像配列を設定することができます。


 
Artyom Trishkin:

テーブルの各セルには画像が必要なので、その配列が必要です。セルの型がCELL_BUTTONの場合は、セルごとに最低1枚の画像で十分であり、型がCELL_CHECKBOXの場合は、最低2枚の画像で十分である。インデックス0の画像はチェックボックス(ボタン)の「押された」状態に対応し、他のインデックスはチェックボックス(ボタン)の「選択された」状態に対応します。

例えば(完成形ではないが、理解のためにはこれで十分だろう):

シンボルのリストがある右のテーブルでは、カラムは1つだけで、CELL_CHECKBOX型です。
arr_chk[2]; arr_chk[0]=m_img_chk0; arr_chk[1]=m_img_chk1;


メイン・テーブル:

セル0には、グラフのオープニング画像が格納されます。セルタイプはCELL_BUTTONで、1次元の画像配列を持つことができます;

セル8は買いのオープニング画像で、タイプはCELL_BUTTON、画像配列は1次元です: arr_img8[1]; arr_img8[0]=m_image_buy;

セル9にはセルのオープニング画像が格納されます - タイプはCELL_BUTTON、画像配列は1次元です: arr_img9[1]; arr_img9[0]=m_image_sell;

テーブルが作成されたら、希望する値で初期化し、希望するセル・タイプを設定し、画像配列を設定します。


最初の画面では、インデックス1の列の画像が消え、2番目の画面では、インデックス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"};
//--- 文字の配列
   //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);
         //--- 直近2ティックのデータを取得する
         MqlTick ticks[];
         if(::CopyTicks(symbol, ticks, COPY_TICKS_ALL, 0, 2) < 2)
            continue;
         //--- 配列を時系列として設定する
         ::ArraySetAsSeries(ticks, true);
         //--- シンボル欄 - シンボル。価格の方向を決定しよう。
         if(c==1)
           {
            int index=0;
            //--- 価格が変わっていない場合
            if(ticks[0].ask==ticks[1].ask && ticks[0].bid==ticks[1].bid)
               index=0;
            //--- ビッド価格が上方修正された場合
            else if(ticks[0].bid > ticks[1].bid)
               index=1;
            //--- ビッド価格が下方に変動した場合
            else if(ticks[0].bid < ticks[1].bid)
               index=2;
            //--- 対応する画像を設定する
            m_canvas_table.ChangeImage(c,r,index,true);
           }
         else
           {
            //--- 価格差欄 - スプレッド(!)
            if(c==3)
              {
               //--- スプレッドの大きさをpips単位で取得・設定する。
               int spread=(int)::SymbolInfoInteger(symbol,SYMBOL_SPREAD);
               m_canvas_table.SetValue(c,r,string(spread),true);
               continue;
              }
            //--- 小数点の桁数を取得する
            int digit=(int)::SymbolInfoInteger(symbol,SYMBOL_DIGITS);
            //--- 価格欄 入札
            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;
              }
            //--- 売値欄
            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;
               //--- ビッド価格が上方修正された場合
               else if(ticks[0].bid>ticks[1].bid)
                  clr=clrBlue;
               //--- ビッド価格が下方に変動した場合
               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