スポンサーリンク

wxWidgetsでスクロールバーを作成(wxScrollBar)

wxWidgetsのwxScrollBarの使用例。これはスクロールバーのみのコントロールになる。

スクロールバーとしての設定はSetScrollbar関数で行う。

https://docs.wxwidgets.org/3.0/classwx_scroll_bar.html#ae69c239fd6af4ebcabf46efa9fc5092e

#include <wx/wx.h>
#include <wx/sizer.h>
#include <wx/frame.h>
#include <wx/panel.h>

class MyFrame : public wxFrame
{

  std::vector<int> _itemlist;
  int row = 3;
  int col = 1;
  int itemcount() { return _itemlist.size(); }

  wxScrollBar* _scroll;
  wxGridSizer* _gridSizer;
public:
  MyFrame() : wxFrame(NULL, wxID_ANY, "wxGridSizer サンプル", wxDefaultPosition, wxSize(400, 300))
  {
    for (size_t i = 0; i < 17; i++) {
      _itemlist.push_back(i);
    }


    int vgap = 2;// 垂直方向の間隔
    int hgap = 2;// 水平方向の間隔
    _gridSizer = new wxGridSizer(row, col, vgap, hgap);

    for (int i = 0; i < row*col; ++i) 
    {
      //// 新しいパネルを作成
      wxPanel* panel = new wxPanel(this/*MyFrameで管理*/, wxID_ANY);

      //// パネルの背景色を設定
      panel->SetBackgroundColour(wxColour(200, 200, 100 * (i + 1) % 256));

      //// パネルをgridSizer追加
      _gridSizer->Add(panel, 1, wxEXPAND);

      // パネルにラベルを追加
      wxStaticText* label = new wxStaticText(panel, wxID_ANY, wxString::Format("Panel %d", i));
      wxBoxSizer* boxSizer = new wxBoxSizer(wxHORIZONTAL);
      boxSizer->Add(label, 1, wxALIGN_CENTER);
      panel->SetSizer(boxSizer);

    }

    // 水平分割のSizer作成
    wxBoxSizer* boxSizer = new wxBoxSizer(wxHORIZONTAL);
    boxSizer->Add(_gridSizer, 1, wxEXPAND);
    
    //スクロールバー作成
    _scroll = new wxScrollBar(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSB_VERTICAL);
    boxSizer->Add(_scroll, 0, wxEXPAND);


    // OnScrollをscrollにBind
    _scroll->Bind(wxEVT_SCROLL_CHANGED, &MyFrame::OnScroll, this);

    _scroll->SetScrollbar(
      0,       // position  スクロールバーの位置
      row,     // thumbSize つまみのサイズ。これは一度に画面上に表示する行数と等しいことが望ましい
      itemcount(), // range   総行数
      2,       // pageSize  ページ単位でのスクロールを行ったときに移動する量
      true     // refresh   trueにするとスクロールバーの位置を更新する
    );

    // 初期表示を行う
    panel_update();

    // MyFrameにgridSizerを指定
    SetSizer(boxSizer);

    Centre();// ウィンドウを画面中央に表示
  }

  // wxScrollBarをクリックしたときに呼び出されるイベントハンドラ
  void OnScroll(wxScrollEvent& event)
  {
    // スクロールバーの位置を取得
    int pos = event.GetPosition();

    // pos をデバッグ出力
    wxLogDebug(wxString::Format("pos = %d", pos));

    panel_update();
  }

  // panelの内容を更新する
  void panel_update() {

    // _scroll の位置を取得
    int pos = _scroll->GetThumbPosition();

    // 一行ずつスクロールしたいので、
    // 一番左上のパネルに表示するアイテム番号を計算
    int offset = pos * col;

    for (int i = 0; i < row * col; ++i)
    {
      // _gridSizerに登録されているpanelを取得
      wxPanel* panel = (wxPanel*)_gridSizer->GetItem(i)->GetWindow();

      // panel上にあるlabelを取得
      wxStaticText* label = (wxStaticText*)panel->GetChildren()[0];

      if ((offset + i) >= itemcount()) {
        // アイテム数を超えたら *** を表示
        label->SetLabelText("***");
      }
      else {

        if (offset + i == itemcount()-1) {
          // 最後のアイテムなら (last item) を表示
          label->SetLabelText(wxString::Format("Panel %d (last item)", _itemlist[offset + i]));
        }
        else {
          // それ以外はアイテム番号を表示
          label->SetLabelText(wxString::Format("Panel %d", _itemlist[offset + i]));
        }
      }
    }
  }
};

class MyApp : public wxApp
{
public:
  virtual bool OnInit()
  {
    MyFrame* frame = new MyFrame();
    frame->Show(true);

    return true;
  }
};

wxIMPLEMENT_APP(MyApp);

 

 

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: