场景:
1.在一次过插入过多的行时,比如3000,wxListCtrl会响应比较慢,出现卡死状态.这时候解决方案可以是参考web的翻页方式,增加上一页和下一页按扭或者
在滚动滚动条到底部时增量加载,增加翻页按钮就不介绍了。wx的bug,还不支持EVT_SCROLLWIN_BOTTOM事件,经测试只有EVT_SCROLLWIN_THUMBTRACK
和EVT_SCROLLWIN_THUMBRELEASE支持.所以可以判断在向下滑动release时增量加载.比较奇怪的是wxListCtrl并不继承wxScroll<T>,却也可以响应这个事件.
界面截图:
代码 gui.cpp:
#include "wx/wxprec.h" #ifndef WX_PRECOMP #include "wx/wx.h" #endif #include "wx/xrc/xmlres.h" #include <assert.h> #include <iostream> #include <stdio.h> #include "wx/listctrl.h" #include "wx/grid.h" #include "wx/event.h" using namespace std; static wxString GetAppRunDirectory() { wxString directory(wxTheApp->argv[0]); directory.Replace(wxT("\\"), wxT("/")); wxString str = directory.BeforeLast('/'); if(str.IsEmpty()) { return wxT("."); } return directory.BeforeLast('/'); } class MyGrid : public wxGrid { DECLARE_DYNAMIC_CLASS(MyGrid) DECLARE_EVENT_TABLE() public: MyGrid():wxGrid(){} bool Create(wxWindow *parent, wxWindowID id, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxWANTS_CHARS, const wxString &name=wxGridNameStr) { return wxGrid::Create(parent,id,pos,size,style,name); } void OnGridScrollButtom(wxScrollWinEvent& evt); }; BEGIN_EVENT_TABLE(MyGrid, wxGrid) EVT_SCROLLWIN(MyGrid::OnGridScrollButtom) END_EVENT_TABLE() IMPLEMENT_DYNAMIC_CLASS(MyGrid, wxGrid) void MyGrid::OnGridScrollButtom(wxScrollWinEvent& evt) { cout << "OnGridScrollButtom1 " << endl; evt.Skip(); } class MyFrame : public wxFrame { public: MyFrame( wxWindow* parent=(wxWindow *)NULL); ~MyFrame(); virtual void Init(); protected: void OnLoadList(wxCommandEvent& evt); void OnLoadGrid(wxCommandEvent& evt); void OnGridScrollButtom(wxScrollWinEvent& evt); private: DECLARE_EVENT_TABLE() wxListCtrl* list_; wxGrid* grid_; }; class MyApp : public wxApp { public: virtual bool OnInit(); virtual int OnExit(); }; IMPLEMENT_APP(MyApp) // 'Main program' equivalent: the program execution "starts" here bool MyApp::OnInit() { if (!wxApp::OnInit()) { return false; } wxInitAllImageHandlers(); wxXmlResource::Get()->InitAllHandlers(); wxString ui_dir = GetAppRunDirectory()+wxT("/Ui"); wxXmlResource::Get()->LoadAllFiles(ui_dir); MyFrame *frame = new MyFrame(NULL); bool loaded = wxXmlResource::Get()->LoadFrame(frame, NULL, "MyFrame1"); assert(loaded); frame->Init(); frame->Show(true); return true; } int MyApp::OnExit() { return 0; } BEGIN_EVENT_TABLE(MyFrame, wxFrame) END_EVENT_TABLE() void MyFrame::Init() { list_ = XRCCTRL(*this, "m_listCtrl1", wxListCtrl); list_->Bind(wxEVT_SCROLLWIN_PAGEUP, wxScrollWinEventHandler(MyFrame::OnGridScrollButtom),this); XRCCTRL(*this, "m_button1", wxButton)->Bind(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MyFrame::OnLoadList), this, XRCID("m_button1")); list_->InsertColumn(0,wxT("No.")); list_->InsertColumn(1,wxT("Name")); list_->InsertColumn(2,wxT("Address")); grid_ = XRCCTRL(*this, "m_grid1", wxGrid); XRCCTRL(*this, "m_button2", wxButton)->Bind(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MyFrame::OnLoadGrid), this, XRCID("m_button2")); grid_->Bind(wxEVT_SCROLLWIN_THUMBTRACK, wxScrollWinEventHandler(MyFrame::OnGridScrollButtom),this); grid_->CreateGrid(0, 0); grid_->SetColLabelSize(12); grid_->SetRowLabelSize(50); grid_->SetDefaultRowSize(36); grid_->SetScrollLineX(1); grid_->SetCellHighlightPenWidth(0); grid_->SetSelectionMode(wxGrid::wxGridSelectRows); grid_->SetUseNativeColLabels(true); grid_->AppendCols(); grid_->SetColLabelValue(0, wxT("TitleName")); grid_->SetColSize(0, 100); grid_->SetColLabelAlignment(wxALIGN_CENTRE, wxALIGN_CENTRE); grid_->AppendCols(); grid_->SetColLabelValue(1, wxT("TitleAddress")); grid_->SetColSize(1, 100); grid_->SetColLabelAlignment(wxALIGN_CENTRE, wxALIGN_CENTRE); } MyFrame::MyFrame(wxWindow* parent) { } MyFrame::~MyFrame() { } void MyFrame::OnLoadList(wxCommandEvent& evt) { cout << "OnLoadList: " << endl; for (int i = 0; i < 100; ++i) { wxString str; str.Printf(wxT("%d"),i); list_->InsertItem(i,str); list_->SetItem(i,1,wxT("name")); list_->SetItem(i,2,wxT("address")); } cout << "HasScrollbar: " << list_->HasScrollbar(wxVERTICAL) << endl; cout << "GetScrollPos: " << list_->GetScrollPos(wxVERTICAL) << endl; cout << "GetScrollRange: " << list_->GetScrollRange(wxVERTICAL) << endl; } void MyFrame::OnGridScrollButtom(wxScrollWinEvent& evt) { cout << "wxScrollWinEvent grid thumb: " << grid_->GetScrollThumb(wxVERTICAL) << " grid pos: " << grid_->GetScrollPos(wxVERTICAL) << " grid Max: " << grid_->GetScrollRange(wxVERTICAL) << ":" << grid_->HasScrollbar(wxVERTICAL) <<endl; cout << "wxScrollWinEvent list thumb: " << list_->GetScrollThumb(wxVERTICAL) << " list pos: " << list_->GetScrollPos(wxVERTICAL) << " list Max: " << list_->GetScrollRange(wxVERTICAL) << ":" << grid_->HasScrollbar(wxVERTICAL) <<endl; evt.Skip(); } void MyFrame::OnLoadGrid(wxCommandEvent& evt) { cout << "OnLoadGrid: " << endl; for (int i = 0; i < 100; ++i) { wxString str; str.Printf(wxT("%d"),i); grid_->InsertRows(i,1,false); //name grid_->SetCellAlignment(wxALIGN_LEFT, i, 0); grid_->SetReadOnly(i, 0, true); grid_->SetCellValue(i, 0, wxT("name")); grid_->SetCellAlignment(wxALIGN_LEFT, i, 1); grid_->SetReadOnly(i, 1, true); grid_->SetCellValue(i, 1, wxT("address")); } }
界面布局代码 ui.xrc
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <resource xmlns="http://www.wxwindows.org/wxxrc" version="2.3.0.1"> <object class="wxFrame" name="MyFrame1"> <style>wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL</style> <size>564,441</size> <bg>#ffffff</bg> <title></title> <centered>1</centered> <aui_managed>0</aui_managed> <object class="wxBoxSizer"> <orient>wxVERTICAL</orient> <object class="sizeritem"> <option>1</option> <flag>wxALL|wxEXPAND</flag> <border>5</border> <object class="wxListCtrl" name="m_listCtrl1"> <style>wxLC_REPORT|wxSIMPLE_BORDER</style> <size>400,200</size> </object> </object> <object class="sizeritem"> <option>0</option> <flag>wxALL</flag> <border>5</border> <object class="wxButton" name="m_button1"> <label>LoadList</label> <default>0</default> </object> </object> <object class="sizeritem"> <option>0</option> <flag>wxALL|wxEXPAND</flag> <border>5</border> <object class="wxGrid" name="m_grid1"> <style>wxSIMPLE_BORDER</style> <size>400,200</size> </object> </object> <object class="sizeritem"> <option>0</option> <flag>wxALL</flag> <border>5</border> <object class="wxButton" name="m_button2"> <label>LoadGrid</label> <default>0</default> </object> </object> </object> </object> </resource>
#Makefile template #http://blog.csdn.net/infoworld CP=cp -p OBJECTDIR=build/Release objects = \ ${OBJECTDIR}/src/gui.o # CC Compiler Flags CXXFLAGS=-m32 -Wall -MMD -MP -MF [email protected] \ -D_LARGEFILE_SOURCE=unknown -DwxDEBUG_LEVEL=0 -DWXUSINGDLL -D__WXMSW__ -DWX_PRECOMP -mthreads CPPFLAGS= \ -Iinclude \ -I. \ -I/E/software/Lib/gui/wxWidgets-2.9.2/include \ -I/E/software/Lib/gui/wxWidgets-2.9.2/win32/release/share/include # Link Libraries and Options LDLIBSOPTIONS= \ -L/E/software/Lib/gui/wxWidgets-2.9.2/win32/release/share \ -lwx_mswu_adv-2.9 -lwx_mswu_core-2.9 -lwx_baseu-2.9 -lwx_mswu_xrc-2.9 .rc: mkdir -p ${OBJECTDIR} mkdir -p dist/Ui/ windres --input-format=rc -O coff -i ui.rc -o ${OBJECTDIR}/ui.o --define __WXMSW__ --include-dir E:/software/Lib/gui/wxWidgets-2.9.2/include .Init: mkdir -p dist ${CP} E:/software/Lib/gui/wxWidgets-2.9.2/win32/release/share/wxmsw292u_adv_gcc_custom.dll dist/ ${CP} E:/software/Lib/gui/wxWidgets-2.9.2/win32/release/share/wxmsw292u_core_gcc_custom.dll dist/ ${CP} E:/software/Lib/gui/wxWidgets-2.9.2/win32/release/share/wxbase292u_xml_gcc_custom.dll dist/ ${CP} E:/software/Lib/gui/wxWidgets-2.9.2/win32/release/share/wxmsw292u_html_gcc_custom.dll dist/ ${CP} E:/software/Lib/gui/wxWidgets-2.9.2/win32/release/share/wxmsw292u_xrc_gcc_custom.dll dist/ ${CP} E:/software/Lib/gui/wxWidgets-2.9.2/win32/release/share/wxbase292u_gcc_custom.dll dist/ ${CP} E:/software/MinGW/bin/libgcc_s_dw2-1.dll dist/ ${CP} E:/software/MinGW/bin/mingwm10.dll dist/ all: .rc ${objects} ${objects_test} mkdir -p dist ${CXX} -m32 -o dist/app -s -Wl,--subsystem,console -mwindows ${objects} ${LDLIBSOPTIONS} ${OBJECTDIR}/ui.o ${CP} ui.xrc dist/Ui/ ${objects}: ${OBJECTDIR}/%.o: %.cpp mkdir -p $(dir $@) rm -fr [email protected] $(COMPILE.cc) $< -o $@ ${objects_test}: ${OBJECTDIR}/%.o: %.cpp mkdir -p $(dir $@) rm -fr [email protected] $(COMPILE.cc) $< -o $@ clean: rm -fr build rm -fr dist