场景:
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:
#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 $@.d \
-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 $@.d
$(COMPILE.cc) $< -o $@
${objects_test}: ${OBJECTDIR}/%.o: %.cpp
mkdir -p $(dir $@)
rm -fr $@.d
$(COMPILE.cc) $< -o $@
clean:
rm -fr build
rm -fr dist
完整程序下载地址: http://download.csdn.net/detail/infoworld/7228253