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);