多列wxListCtrl使用技巧
以官方Wiki的minimal example为例:
// Example uses fictive class "Item" and fictive getters to access them. Adapt for your needs
class MyFrame : public wxFrame
{
wxListCtrl* m_item_list;
public:
MyFrame() : wxFrame(NULL, wxID_ANY, wxT("Hello wxWidgets"), wxPoint(50,50), wxSize(800,600))
{
wxPanel* mainPane = new wxPanel(this);
wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
m_item_list = new wxListCtrl(mainPane, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT);
// Add first column
wxListItem col0;
col0.SetId(0);
col0.SetText( _("Foo") );
col0.SetWidth(50);
m_item_list->InsertColumn(0, col0);
// Add second column
wxListItem col1;
col1.SetId(1);
col1.SetText( _("Name") );
m_item_list->InsertColumn(1, col1);
// Add third column
wxListItem col2;
col2.SetId(2);
col2.SetText( _("Comments") );
m_item_list->InsertColumn(2, col2);
const int item_amount = getItemAmount();
for (int n=0; n<item_amount; n++)
{
Item* curritem = getItem(n);
wxListItem item;
item.SetId(n);
item.SetText( curritem->getName() );
m_item_list->InsertItem( item );
// set value in first column
if (!curritem->isFoo())
{
m_item_list->SetItem(n, 0, wxT("Foo"));
}
else
{
m_item_list->SetItem(n, 0, wxT("Bar"));
}
// set value in second column
m_item_list->SetItem(n, 1, curritem->getName());
// set value in third column
m_item_list->SetItem(n, 2, curritem->getDescription());
}
sizer->Add(m_item_list,1, wxEXPAND | wxALL, 10);
mainPane->SetSizer(sizer);
}
};
class MyApp: public wxApp
{
wxFrame* m_frame;
public:
bool OnInit()
{
m_frame = new MyFrame();
m_frame->Show();
return true;
}
};
IMPLEMENT_APP(MyApp)
由于官方的API文档描述的比较简单,整理一下使用时的注意事项:
要使用带表头的多列List,初始化时,需有wxLC_REPORT的flag(注意不同flag会有冲突)
使用ClearAll清除表格时,表头(Columns)也会一起被清除,需要重新添加
添加表头有两种方式:
AppendColumn,简单方便
构造一个wxListItem后,再InsertColumn(官方Minimal Example的方式)
- 添加数据的方式有点奇怪,需分为两步:
先获取到索引(可用GetItemCount方法取当前Item的数量作为index),再使用InsertItem插入一个Item,这个方法会返回新Item的index,作为下一步使用
插入Item后,使用SetItem(index,column,label,imageIndex=-1)方法,给刚才的Item设置各列显示的数据,如需设置自定义数据、图片、字体等高级功能,可用wxListItem的重载版本
新增Item的示例代码如下:
int TrayThem::MainWidget::cbReloadPrograms(void *argument, int argc,
char **argv, char **azColName) {
if (argument == nullptr) {
return -1;
}
auto mw = static_cast<TrayThem::MainWidget *>(argument);
auto programs = mw->m_lvPrograms;
int index = programs->GetItemCount();
programs->InsertItem(index, "");
for (int i = 0; i < argc; i++) {
programs->SetItem(index, i, argv[i] == nullptr ? "" : argv[i]);
}
return 0;
}
关于事件,常用的事件主要有wxEVT_LIST_ITEM_SELECTED和wxEVT_LIST_ITEM_DESELECTED,分别对应选中和取消选中Item,对应的事件处理函数原型为:
void handler(wxListEvent &event);
其中,event.GetItem可取到选中的Item,GetText可取到对应的Label,如果是单行选择模式的List(初始化时,设置了wxLC_SINGLE_SEL的flag),则GetText会返回第一列的Label
获取同一行中其它列的Text,可使用GetItemLabel方法,示例代码如下:
void TrayThem::MainWidget::OnProgramSelected(wxListEvent &event) {
wxListItem item = event.GetItem();
this->m_SelectedId = item.GetText();
this->m_SelectedProgram.program_id = this->m_SelectedId;
int col = item.GetColumn();
this->m_SelectedProgram.running_status =
this->m_lvPrograms->GetItemText(item, ++col);
this->m_SelectedProgram.program_name =
this->m_lvPrograms->GetItemText(item, ++col);
this->m_SelectedProgram.autostart =
this->m_lvPrograms->GetItemText(item, ++col) == "1" ? true : false;
this->m_SelectedProgram.execution =
this->m_lvPrograms->GetItemText(item, ++col);
this->m_SelectedProgram.working_directory =
this->m_lvPrograms->GetItemText(item, ++col);
this->m_SelectedProgram.parameters =
this->m_lvPrograms->GetItemText(item, ++col);
}
Subscribe to my newsletter
Read articles from 源赖朝 directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by