12.1 wxTreeCtrl
树状控件以层的形式展示信息,它的子项可以展开也可以合并.下图演示了 wxWidgets 的树状控件例子,它正以不同的字体和风格以及颜色进行展示.每一个树状控件的子项都代表一个 wxtreeItemId 对象,它拥有一个文本标签和一个可选图标,并且文本和图标的内容都可以动态修改.树状控件可以以单选或者多选的形式创建.如果你希望在 wxtreeItemId 上绑定一些数据,你需要实现自己的 wxTreeItemData 派生类,然后调用 wxTreeCtrl::SetItemData 函数以及 wxTreeCtrl::GetItemData 函数.这个数据在子项被释放的时候将会被一并释放(delete 调用),如果你将其指向你实际的数据,需要注意避免重复释放。
因为应用程序可以检测到树状控件的子项被单击的事件,你可以用这个特点通过更改子项的图片来达到模拟其他的控件的目的.比如说,你可以很容易用树状控件的子项来模拟一个复选框。
下面的代码演示了怎样创建一个树状控件,定义其子项的绑定数据以及图片:
#include "wx/treectrl.h"
// 声明一个代表和子项绑定的数据的类
class MyTreeItemData : public wxTreeItemData
{
public:
MyTreeItemData(const wxString& desc) : m_desc(desc) { }
const wxString& GetDesc() const { return m_desc; }
private:
wxString m_desc;
};
// 子项相关的图片
#include "file.xpm"
#include "folder.xpm"
// 创建一个树状控件
wxTreeCtrl* treeCtrl = new wxTreeCtrl(
this, wxID_ANY, wxPoint(0, 0), wxSize(400, 400),
wxTR_HAS_BUTTONS|wxTR_SINGLE);
wxImageList* imageList = new wxImageList(16, 16);
imageList->Add(wxIcon(folder_xpm);
imageList->Add(wxIcon(file_xpm);
treeCtrl->AssignImageList(imageList);
// 根节点使用文件夹图标,而两个字节点使用文件图标
wxTreeItemId rootId = treeCtrl->AddRoot(wxT("Root"), 0, 0,
new MyTreeItemData(wxT("Root item")));
wxTreeItemId itemId1 = treeCtrl->AppendItem(rootId,
wxT("File 1"), 1, 1,
new MyTreeItemData(wxT("File item 1")));
wxTreeItemId itemId2 = treeCtrl->AppendItem(rootId,
wxT("File 2"), 1, 1,
new MyTreeItemData(wxT("File item 2")));
wxTreeCtrl 的窗口类型
wxTreeCtrl 有如下表所示的额外的窗口类型:
wxtr_DEFAULT_STYLE | 这个值是各个平台上树状控件实现和默认值最接近的值 |
---|---|
wxtr_EDIT_LABELS | 是否子项文本可编辑 |
wxtr_NO_BUTTONS | 不必显示用于展开或者合并子项的按钮 |
wxtr_HAS_BUTTONS | 显示用于展开或者合并子项的按钮 |
wxTR_NO_LINES | 不必显示用于表示层级关系的垂直虚线 |
wxtr_FULL_ROW_HIGHLIGHT | 当选中某个子项的时候高亮显示整行(在 windows 平台上,除非设置了 wxtr_NO_LINES,否则这个类型将被忽略) |
wxtr_LINES_AT_ROOT | 不必显示根节点之间的连线.这个类型只有在设置 wxtr_HIDE_ROOT 并且没有设置 wxtr_NO_LINES 的时候有效 |
wxtr_HIDE_ROOT | 不显示根节点,这将导致第一层的字节点成为一系列根节点 |
wxtr_ROW_LINES | 使用这个类型在已显示的行之间绘制一个高对比的边界 |
wxTR_HAS_VARIABLE_ROW_HEIGHT | 设置这个类型允许各行采用不同的高度,否则各行都将采用和最大的行高同样的高度.这个类仅适用于树状控件的标准实现(而非各个平台的原生实现) |
wxtr_SINGLE | 单选模式 |
wxtr_MULTIPLE | 多选模式 |
wxtr_EXTENDED | 允许多选非连续的子项(该功能仅是部分实现) |
wxTreeCtrl 的事件
树状控件产生 wxtreeEvent 类型的事件,这种事件可以在父子关系的窗口之间传递。
EVT_TREE_BEGIN_DRAG(id, func)EVT_TREE_BEGIN_RDRAG(id, func) | 在用户开始拖放操作的时候产生,这个事件的使用细节请参考第 11 章,"剪贴板和拖放操作" |
---|---|
EVT_TREE_BEGIN_LABEL_EDIT(id, func) EVT_TREE_END_LABEL_EDIT(id, func) | 当用户开始编辑或者刚刚完成编辑子项标签的时候产生 |
EVT_TREE_DELETE_ITEM(id, func) | 当某个子项被删除的时候产生 |
EVT_TREE_GET_INFO(id, func) | 当某个子项的数据被请求的时候产生 |
EVT_TREE_SET_INFO(id, func) | 当某个子项的数据被设置的时候产生 |
EVT_TREE_ITEM_ACTIVATED(id, func) | 当某个子项被激活(双击或者使用键盘选择) 的时候产生 |
EVT_TREE_ITEM_COLLAPSED(id, func) | 给定的子项已被收缩(合并) 的时候产生 |
EVT_trEE_ITEM_COLLAPSING(id, func) | 给定的子项即将收缩(合并) 的时候产生,这个事件可以被 Veto 以阻止收缩。 |
EVT_TREE_ITEM_EXPANDED(id, func) | 给定子项已被展开的时候产生 |
EVT_TREE_ITEM_EXPANDING(id, func) | 给定子项即将展开的时候产生,这个事件可以被 Veto 以阻止展开 |
EVT_TREE_SEL_CHANGED(id, func) | 选中的子项发生变化以后(新的子项被选中或者旧的选中项不被选中的时候) 产生 |
EVT_TREE_SEL_CHANGING(id, func) | 选中的子项即将发生变化的时候产生,该事件可以被 Veto 以阻止变化产生 |
EVT_TREE_KEY_DOWN(id, func) | 检测针对该树状控件的键盘事件 |
EVT_TREE_ITEM_GET_TOOLTIP(id, func) | 这个事件仅支持 windows 平台,它使得你可以给某个子项设置单独的工具提示 |
wxTreeCtrl 的成员函数
下面列出了 wxTreeCtrl 控件的一些重要的成员函数。
使用 AddRoot 函数增加第一个子项,然后使用 AppendItem, InsertItem 或 PrependItem 来增加随后的子项.使用 Delete 移除一个子项,使用 DeleteAllItems 删除某个子项所有的子项,或者使用 DeleteChildren 删除某个子项的所有直接子项。
使用 SetItemText 设置某个子项的标签,使用 SetItemTextColour,SetItemBackgroundColour,SetItemBold 和 SetItemFont 来设置标签的外观。
如果你想给某个子项指定一幅图片,首先需要使用 SetImageList 函数将某个图片列表和这个树状控件绑定.每个子项可以指定四个状态的图片,分别是 wxTReeItemIcon_Normal,wxTReeItemIcon_Selected, wxtreeItemIcon_Expanded 和 wxTReeItemIcon_SelectedExpanded,你可以使用 SetItemImage 函数给每个状态指定一个图片列表中图片索引.如果你只给 wxTReeItemIcon_Normal 状态指定了一个索引,那么别的状态也将都使用这个图片。
使用 Scroll 函数以便将某个子项移动到可见区域,使用 EnsureVisible 使得这个子项在需要的时候展开以便其可以位于可见区域.使用 Expand 函数展开某个子项,Collapse 和 CollapseAndReset 函数合并某个子项,后者还将移除其所有的子项,如果你正在使用的树状控件有很多子项,你可能希望只增加可见部分的子项以便提高性能.在这种情况下,你可以处理 EVT_TREE_ITEM_EXPANDING 事件,在需要的时候才增加子项,在收缩的时候则移除所有子项.而且你还需要调用 SetItemHasChildren 函数以便没有子项的子项也可以显示一个可扩展按钮,即使它真的没有。
使用 SelectItem 选择或者去选择某个子项.如果是单选类型,你可以使用 GetSelection 函数得到正被选中的子项,如果当前没有子项被选中,则返回一个未初始化的 wxTReeItemId,你可以调用 wxTreeItemId::IsOk 函数来判断其有效性.而对于多选类型,你可以使用 GetSelections 函数获取当前选中的子项,你需要传递一个 wxArrayTreeItemItemIds 类型的引用作为参数. Unselect 函数在单选情况下去选中当前的子项,而 UnselectAll 函数则用在多选情况下去选中所有正被选中的子项,UnselectItem 函数可以用来在多选情况下去选中某一个子项。
遍历某个树状控件的所有子项也有多种方法:你可以先使用 GetRootItem 函数获得根节点,然后使用 GetFirstChild 和 GetNextChild 遍历所有子项.使用 GetNextSibling 和 GetPrevSibling 获取某个子项后一个和前一个兄弟节点.使用 ItemHasChildren 函数判断某个子项是否有字节点,使用 GetParent 函数获取某个子项的父节点.GetCount 函数则用来返回树状控件中所有子项的个数,而 GetChildrenCount 则返回某个子项的字节点的数目。
HitTest 函数在实现你自己拖放的时候是很有用的,它使得你可以通过鼠标位置找到这个位置对应的子项以及子项的某个特定部分.具体返回值请参考相关手册中的内容.使用 GetBoundingRect 函数可以得到某个子项对应的矩形区域。
更多关于树状控件的信息请参考使用手册以及 samples/treectrl 中的 wxTreeCtrl 例子。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论