erlang 中wxListCtrl的 使用总结
-module(list_ctrl).
-behaviour(wx_object).
%% wx_object callbacks
-export([new/0, start/1, destroy/0]).
-export([init/1,
terminate/2,
code_change/3,
handle_info/2,
handle_call/3,
handle_cast/2,
handle_event/2]).
-include_lib("wx/include/wx.hrl").
-define(FIRST_COL, 0).
-define(SECOND_COL, 1).
-define(THIRD_COL, 2).
-record(state, {frame,
panel,
list
}).
%%%===================================================================
%%% API
%%%===================================================================
%%--------------------------------------------------------------------
%% @doc
%% @spec
%% @end
%%--------------------------------------------------------------------
new() ->
_WX = wx:new(),
Size = {size, {400, 600}},
Pos = {pos, {200, 300}},
Style = {style, ?wxDEFAULT_FRAME_STYLE bor ?wxMAXIMIZE},
NOptions = [Pos, Size, Style],
Frame = makeFrame("wxListCtrl 总结", NOptions),
start([{parent, Frame}]).
start(Config) ->
wx_object:start_link({local, ?MODULE}, ?MODULE, Config, []).
destroy() ->
wx_object:call(?MODULE, shutdown).
%%--------------------------------------------------------------------
%% @doc
%% @spec
%% @end
%%--------------------------------------------------------------------
init(Config) ->
wx:batch(fun() -> do_init(Config) end).
handle_info(_Msg, State) ->
{noreply, State}.
handle_call(shutdown, _From, #state{panel = Panel} = State) ->
wxFrame:destroy(Panel),
{stop, normal, ok, State};
handle_call(_Msg, _From, State) ->
{reply, {error, ?MODULE},State}.
handle_cast(_Msg, State) ->
{noreply,State}.
%%单击选中某一行,默认情况下可以多选
handle_event(#wx{event = #wxList{itemIndex = Item, type = command_list_item_selected}}, State) ->
io:format("Item ~p selected.\n",[Item]),
{noreply, State};
%%windows下单击第二次是编辑状态,但Linux下是dselect,而且即使有图标window下是可以编辑的
handle_event(#wx{event = #wxList{itemIndex = Item, type = command_list_item_deselected}}, State) ->
io:format("Item ~p command_list_item_deselected.\n",[Item]),
{noreply, State};
%%双击左键
handle_event(#wx{event = #wxList{itemIndex = Item, type = command_list_item_activated}}, State) ->
io:format("Item ~p command_list_item_activated.\n",[Item]),
{noreply, State};
%%单击右键,事件处理首先获取编辑前的item的label
handle_event(#wx{event = #wxList{itemIndex = Item, type = command_list_item_right_click}},
#state{list = ListCtrl2} = State) ->
io:format("Item ~p, Text = ~p, command_list_item_right_click.\n",
[Item, wxListCtrl:getItemText(ListCtrl2, Item)]),
{noreply, State};
%%开始用左键拖拽item
handle_event(#wx{event = #wxList{itemIndex = Item, type = command_list_begin_drag}}, State) ->
io:format("Item ~p command_list_begin_drag.\n",[Item]),
{noreply, State};
%%开始用右键拖拽item,事件处理:删除拖拽的item
handle_event(#wx{event = #wxList{itemIndex = Item, type = command_list_begin_rdrag}},
#state{list = ListCtrl2} = State) ->
io:format("Item ~p command_list_begin_rrrrrdrag.\n",[Item]),
wxListCtrl:deleteItem(ListCtrl2, Item),
{noreply, State};
%%删除item
handle_event(#wx{event = #wxList{itemIndex = Item, type = command_list_delete_item}}, State) ->
io:format("Item ~p command_list_delete_item.\n",[Item]),
{noreply, State};
%%开始编辑某个item的labl
handle_event(#wx{event = #wxList{itemIndex = Item, type = command_list_begin_label_edit}}, State) ->
io:format("Item ~p command_list_begin_label_edit.\n",[Item]),
{noreply, State};
%%item的label编辑完成,点击Enter之后
handle_event(#wx{event = #wxList{itemIndex = Item, type = command_list_end_label_edit}},
#state{list = ListCtrl2} = State) ->
io:format("the Item data now is ~p~n", [wxListCtrl:getItemData(ListCtrl2, Item)]),
io:format("Item ~p command_list_end_label_edit.\n",[Item]),
{noreply, State};
%%插入item
handle_event(#wx{event = #wxList{itemIndex = Item, type = command_list_insert_item}},
#state{list = ListCtrl2} = State) ->
io:format("Item ~p command_list_insert_item.\n",[Item]),
{noreply, State};
%%左键选择某一列
handle_event(#wx{event = #wxList{itemIndex = Item, col = Col, type = command_list_col_click}}, State) ->
io:format("Item ~p, Col = ~p command_list_col_click.\n",[Item, Col]),
{noreply, State};
%%右键选择某一列
handle_event(#wx{event = #wxList{itemIndex = Item, type = command_list_col_right_click}}, State) ->
io:format("Item ~p command_list_col_right_click.\n",[Item]),
{noreply, State};
%%在list中按下按键,并捕获按键
handle_event(#wx{event = #wxList{itemIndex = Item, code = Code, type = command_list_key_down}},
#state{list = ListCtrl2} = State) ->
io:format("Item ~p ,Text = ~p, Code = ~p.\n", [Item, Code, wxListCtrl:getItemText(ListCtrl2, Item)]),
case Code of
%%重新按照item关联的数据排序
$a ->
io:format("begin resort_accord_to_integer_item~n"),
resort_accord_to_integer_item(ListCtrl2);
$d ->
io:format("delete allItems~n"),
%%删除所有的item
% wxListCtrl:deleteAllItems(ListCtrl2);
% wxListCtrl:deleteColumn(ListCtrl2, 1);
%%删除item
% wxListCtrl:deleteItem (ListCtrl2, 1);
%%给第五行item重新设置label
wxListCtrl:clearAll(ListCtrl2),
wxListCtrl:insertColumn(ListCtrl2, ?FIRST_COL, "First New", []),
wxListCtrl:insertColumn(ListCtrl2, ?SECOND_COL, "Second New", []),
wxListCtrl:insertColumn(ListCtrl2, ?THIRD_COL, "Third New", []);
$i ->
io:format("setLabel"),
wxListCtrl:setItemText(ListCtrl2, 5, "setItemText");
%%给所选择行,第一列设置关联图标列表中第二个图标
$s ->
io:format("setItemColumnImage"),
wxListCtrl:setItemColumnImage(ListCtrl2, Item, 1, 2);
%%新加入一行和一列
$n ->
ListItem = wxListItem:new(),
wxListItem:setId(ListItem, wxListCtrl:getItemCount(ListCtrl2)),
wxListItem:setBackgroundColour(ListItem, {0, 0, 0, 255}),
wxListItem:setText(ListItem, "wxListItem"),
wxListCtrl:insertItem (ListCtrl2, ListItem),
ListColumn = wxListItem:new(),
wxListItem:setText (ListColumn, "wxListItem:setText"),
io:format("getColumnCount = ~p~n", [wxListCtrl:getColumnCount(ListCtrl2)]),
wxListCtrl:insertColumn(ListCtrl2, wxListCtrl:getColumnCount(ListCtrl2), "NewColumn", []),
wxListCtrl:setColumn(ListCtrl2, wxListCtrl:getColumnCount(ListCtrl2), ListColumn);
%%获取每一页中item个数,以及给list设置为黑色
$c ->
Re = wxListCtrl:getCountPerPage(ListCtrl2),
io:format("getCountPerPage = ~p~n", [Re]),
wxListCtrl:setBackgroundColour(ListCtrl2, {0,0,0,255});
%%从第三个item开始查找label为“4”的item
$f ->
Result = wxListCtrl:findItem(ListCtrl2, 3, "4", [{partial, true}]),
io:format("find Result = ~p~n", [Result]);
%5设置第三个item可以编辑
$e ->
io:format("Editable~n"),
wxListCtrl:editLabel(ListCtrl2, 3);
%%获取item空间大小,并设置第一个item的label为蓝色
$p ->
io:format("Rect = ~p~n", [wxListCtrl:getItemRect(ListCtrl2, 1)]),
io:format("getColumnWidth = ~p~n", [wxListCtrl:getColumnWidth(ListCtrl2, 1)]),
io:format("getColumnCount = ~p~n", [wxListCtrl:getColumnCount(ListCtrl2)]),
io:format("Spacing = ~p~n", [wxListCtrl:getItemSpacing(ListCtrl2)]),
wxListCtrl:setItemTextColour(ListCtrl2, 1, ?wxBLUE),
io:format("position = ~p~n", [wxListCtrl:getItemPosition(ListCtrl2, 1)]);
_ ->
ok
end,
{noreply, State};
handle_event(#wx{}, #state{} = State) ->
{noreply, State}.
code_change(_, _, State) ->
{stop, ignore, State}.
terminate(_Reason, _State) ->
ok.
%%%===================================================================
%%% Internal functions
%%%===================================================================
do_init(Config) ->
Parent = proplists:get_value(parent, Config),
Panel = wxPanel:new(Parent, []),
MainSizer = wxStaticBoxSizer:new(?wxVERTICAL, Panel,
[{label, "wxListCtrl "}]),
Notebook = wxNotebook:new(Panel, 1, [{style, ?wxBK_DEFAULT}]),
%% style 1: wxLC_LIST风格的wxListCtrl,
ListCtrl1 = wxListCtrl:new(Notebook, [{style, ?wxLC_LIST bor ?wxLC_EDIT_LABELS}]),
[wxListCtrl:insertItem(ListCtrl1, Int, "Item "++integer_to_list(Int)) ||
Int <- lists:seq(0,50)],
%% style 2: 行和列之间有间隔线的report view
ListCtrl2 = create_list_ctrl(Notebook, [{style, ?wxLC_REPORT bor ?wxLC_HRULES
bor ?wxLC_EDIT_LABELS}]),
insert_image(ListCtrl2),
%% style 3: small icon view 是图标和Lable 纵向排列的
ListCtrl3 = wxListCtrl:new(Notebook, [{style, ?wxLC_SMALL_ICON}]),
[wxListCtrl:insertItem(ListCtrl3, Int, "Item "++integer_to_list(Int)) ||
Int <- lists:seq(0,50)],
insert_image(ListCtrl3) ,
wxListCtrl:setTextColour(ListCtrl3, ?wxBLUE),
%% style 4 :virtual report(with millions of items without consuming much memory)
ListCtrlOpts = virtual_control_options(),
ListCtrl4 = wxListCtrl:new(Notebook, ListCtrlOpts),
%% actual setIamgeList is equal to assignImageList
wxListCtrl:setImageList(ListCtrl4, get_image_list(), ?wxIMAGE_LIST_SMALL),
wxListCtrl:insertColumn(ListCtrl4, 0, "Column 1"),
wxListCtrl:insertColumn(ListCtrl4, 1, "Column 2"),
wxListCtrl:setColumnWidth(ListCtrl4, 0, 200),
wxListCtrl:setColumnWidth(ListCtrl4, 1, 200),
wxListCtrl:setItemCount(ListCtrl4, 1000000),
wxListCtrl:connect(ListCtrl2, command_list_item_selected, []),
wxListCtrl:connect(ListCtrl2, command_list_item_deselected, []),
wxListCtrl:connect(ListCtrl2, command_list_item_right_click, []),
wxListCtrl:connect(ListCtrl2, command_list_begin_drag, []),
wxListCtrl:connect(ListCtrl2, command_list_begin_rdrag, []),
wxListCtrl:connect(ListCtrl2, command_list_begin_label_edit, []),
wxListCtrl:connect(ListCtrl2, command_list_end_label_edit, []),
wxListCtrl:connect(ListCtrl2, command_list_delete_item, []),
wxListCtrl:connect(ListCtrl2, command_list_key_down, []),
wxListCtrl:connect(ListCtrl2, command_list_col_click, []),
wxListCtrl:connect(ListCtrl2, command_list_col_right_click, []),
wxListCtrl:connect(ListCtrl2, command_list_insert_item, []),
wxListCtrl:connect(ListCtrl2, command_list_item_activated, []),
wxNotebook:addPage(Notebook, ListCtrl2, "normal Report", []),
wxNotebook:addPage(Notebook, ListCtrl1, "List", []),
wxNotebook:addPage(Notebook, ListCtrl3, "Small icon view", []),
wxNotebook:addPage(Notebook, ListCtrl4, "Virtual Report", []),
%% Add to sizers
wxSizer:add(MainSizer, Notebook, [{proportion, 1},
{flag, ?wxEXPAND}]),
wxPanel:setSizer(Panel, MainSizer),
wxFrame:show(Parent),
{Panel, #state{panel = Panel, list = ListCtrl2}}.
create_list_ctrl(Win, Options) ->
ListCtrl = wxListCtrl:new(Win, Options),
wxListCtrl:insertColumn(ListCtrl, ?FIRST_COL, "First Col", []),
wxListCtrl:insertColumn(ListCtrl, ?SECOND_COL, "Second Col", []),
wxListCtrl:insertColumn(ListCtrl, ?THIRD_COL, "Third Col", []),
Fun =
fun(Int) ->
Name = integer_to_list(Int),
wxListCtrl:insertItem(ListCtrl, Int, ""),
wxListCtrl:setItem(ListCtrl, Int, ?FIRST_COL, Name),
wxListCtrl:setItem(ListCtrl, Int, ?SECOND_COL, "Second "++Name),
wxListCtrl:setItem(ListCtrl, Int, ?THIRD_COL, "Third "++Name),
wxListCtrl:setItemData(ListCtrl, Int, Int + 10)
end,
wx:foreach(Fun, lists:seq(0, 50)),
ListCtrl.
get_image_list() ->
ImageList = wxImageList:new(16,16),
wxImageList:add(ImageList, wxArtProvider:getBitmap("wxART_COPY", [{size, {16,16}}])),
wxImageList:add(ImageList, wxArtProvider:getBitmap("wxART_MISSING_IMAGE", [{size, {16,16}}])),
wxImageList:add(ImageList, wxArtProvider:getBitmap("wxART_QUESTION", [{size, {16,16}}])),
wxImageList:add(ImageList, wxArtProvider:getBitmap("wxART_WARNING", [{size, {16,16}}])),
ImageList.
insert_image(ListCtrl) ->
ImageList = get_image_list(),
wxListCtrl:assignImageList(ListCtrl, ImageList, ?wxIMAGE_LIST_SMALL),
Fun =
fun(Item) ->
case Item rem 4 of
0 ->
wxListCtrl:setItemBackgroundColour(ListCtrl, Item, {240,240,240,255}),
wxListCtrl:setItemImage(ListCtrl, Item, 0);
1 ->
wxListCtrl:setItemImage(ListCtrl, Item, 1);
2 ->
wxListCtrl:setItemImage(ListCtrl, Item, 2),
wxListCtrl:setItemBackgroundColour(ListCtrl, Item, {240,240,240,255});
_ ->
wxListCtrl:setItemImage(ListCtrl, Item, 3)
end
end,
wx:foreach(Fun, lists:seq(0, wxListCtrl:getItemCount(ListCtrl) -1)),
ListCtrl.
%%--------------------------------------------------------------------
%% @doc
%% @spec
%% @end
%%--------------------------------------------------------------------
resort_accord_to_integer_item(ListCtrl) ->
Fun =
fun(Int) ->
Id = list_to_integer(wxListCtrl:getItemText(ListCtrl, Int)),
io:format("Id = ~p~n", [Id]),
wxListCtrl:setItemData(ListCtrl, Int, 100 - Id)
end,
wx:foreach(Fun, lists:seq(0, wxListCtrl:getItemCount(ListCtrl) -1)),
wxListCtrl:sortItems(ListCtrl, fun(Item1, Item2) ->
case Item1 - Item2 < 0 of
false ->
1;
true ->
-1
end
end).
virtual_control_options() ->
ImageAttr = wxListItemAttr:new(),
wxListItemAttr:setTextColour(ImageAttr, {190, 25, 25}),
ListCtrlOpts = [{style, ?wxLC_REPORT bor ?wxLC_VIRTUAL },
{onGetItemText, fun(_This, Item, 0) ->
"Row " ++ integer_to_list(Item);
(_, Item, 1) when Item rem 5 == 0 ->
"Column 2";
(_, _, _) ->
""
end},
{onGetItemAttr, fun(_This, Item) when Item rem 3 == 0 ->
ImageAttr;
(_This, _Item) ->
wx:typeCast(wx:null(), wxListItemAttr)
end},
{onGetItemColumnImage, fun(_This, Item, 1) ->
Item rem 4;
(_, _, _) ->
-1
end}
],
ListCtrlOpts.
makeFrame(Title, Options) ->
Frame = wxFrame:new(wx:null(), ?wxID_ANY, Title, Options),
MenuSet = wxMenu:new(),
MenuHelp = wxMenu:new(),
wxMenu:append(MenuHelp, 1, "关于..."),
MenuBar = wxMenuBar:new(),
wxMenuBar:append(MenuBar, MenuSet, "设置"),
wxMenuBar:append(MenuBar, MenuHelp, "帮助"),
wxFrame:setMenuBar(Frame, MenuBar),
wxFrame:createStatusBar(Frame),
wxFrame:setStatusText(Frame,"Erlang wxListCtrl"),
wxFrame:connect(Frame, command_menu_selected),
Frame.
获取某一行某一列的cell数据方法(因为在wxErlang 中获取某一列的参数默认是0, 不能直接获取任意一行一列的Cell数据):
Cell = wxListItem:new(), wxListItem:setId(Cell, Index), wxListItem:setColumn(Cell, Column), wxListItem:setMask(Cell, ?wxLIST_MASK_TEXT), wxListCtrl:getItem(ListView, Cell), N = wxListItem:getText(Cell),