gtk_tut-12.html

来自「gtk1.2的教程」· HTML 代码 · 共 872 行 · 第 1/3 页

HTML
872
字号
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><HTML><HEAD> <META NAME="GENERATOR" CONTENT="SGML-Tools 1.0.9"> <TITLE>GTK v1.2 Tutorial: Tree Widget </TITLE> <LINK HREF="gtk_tut-13.html" REL=next> <LINK HREF="gtk_tut-11.html" REL=previous> <LINK HREF="gtk_tut.html#toc12" REL=contents></HEAD><BODY TEXT="#CCCCCC" BGCOLOR="#000000" LINK="#33cc00" VLINK="#009900" ALINK="#FF0000"><A HREF="gtk_tut-13.html">Next</A><A HREF="gtk_tut-11.html">Previous</A><A HREF="gtk_tut.html#toc12">Contents</A><HR><H2><A NAME="sec_Tree_Widgets"></A> <A NAME="s12">12. Tree Widget </A></H2><P>The purpose of tree widgets is to display hierarchically-organizeddata. The Tree widget itself is a vertical container for widgets oftype TreeItem. Tree itself is not terribly different fromCList - both are derived directly from Container, and theContainer methods work in the same way on Tree widgets as onCList widgets. The difference is that Tree widgets can be nestedwithin other Tree widgets. We'll see how to do this shortly.<P>The Tree widget has its own window, and defaults to a whitebackground, as does CList. Also, most of the Tree methods work inthe same way as the corresponding CList ones. However, Tree isnot derived from CList, so you cannot use them interchangeably.<P><P><H2><A NAME="ss12.1">12.1 Creating a Tree</A></H2><P>A Tree is created in the usual way, using:<P><BLOCKQUOTE><CODE><PRE>GtkWidget *gtk_tree_new( void );</PRE></CODE></BLOCKQUOTE><P>Like the CList widget, a Tree will simply keep growing as moreitems are added to it, as well as when subtrees are expanded.  Forthis reason, they are almost always packed into aScrolledWindow. You might want to use gtk_widget_set_usize() on thescrolled window to ensure that it is big enough to see the tree'sitems, as the default size for ScrolledWindow is quite small.<P>Now that you have a tree, you'll probably want to add some items toit.  <A HREF="#sec_Tree_Item_Widget">The Tree Item Widget</A> belowexplains the gory details of TreeItem. For now, it'll suffice tocreate one, using:<P><BLOCKQUOTE><CODE><PRE>GtkWidget *gtk_tree_item_new_with_label( gchar *label );</PRE></CODE></BLOCKQUOTE><P>You can then add it to the tree using one of the following (see<A HREF="#sec_Tree_Functions">Functions and Macros</A>below for more options):<P><BLOCKQUOTE><CODE><PRE>void gtk_tree_append( GtkTree    *tree,                       GtkWidget *tree_item );void gtk_tree_prepend( GtkTree   *tree,                       GtkWidget *tree_item );</PRE></CODE></BLOCKQUOTE><P>Note that you must add items to a Tree one at a time - there is noequivalent to gtk_list_*_items().<P><H2><A NAME="ss12.2">12.2 Adding a Subtree</A></H2><P>A subtree is created like any other Tree widget. A subtree is addedto another tree beneath a tree item, using:<P><BLOCKQUOTE><CODE><PRE>void gtk_tree_item_set_subtree( GtkTreeItem *tree_item,                                GtkWidget   *subtree );</PRE></CODE></BLOCKQUOTE><P>You do not need to call gtk_widget_show() on a subtree before or afteradding it to a TreeItem. However, you <EM>must</EM> have added theTreeItem in question to a parent tree before callinggtk_tree_item_set_subtree(). This is because, technically, the parentof the subtree is <EM>not</EM> the GtkTreeItem which "owns" it, butrather the GtkTree which holds that GtkTreeItem.<P>When you add a subtree to a TreeItem, a plus or minus sign appearsbeside it, which the user can click on to "expand" or "collapse" it,meaning, to show or hide its subtree. TreeItems are collapsed bydefault. Note that when you collapse a TreeItem, any selecteditems in its subtree remain selected, which may not be what the userexpects.<P><H2><A NAME="ss12.3">12.3 Handling the Selection List</A></H2><P>As with CList, the Tree type has a <CODE>selection</CODE> field, andit is possible to control the behaviour of the tree (somewhat) bysetting the selection type using:<P><BLOCKQUOTE><CODE><PRE>void gtk_tree_set_selection_mode( GtkTree          *tree,                                  GtkSelectionMode  mode );</PRE></CODE></BLOCKQUOTE><P>The semantics associated with the various selection modes aredescribed in the section on the CList widget. As with the CListwidget, the "select_child", "unselect_child" (not really - see <A HREF="#sec_Tree_Signals">Signals</A> below for an explanation),and "selection_changed" signals are emitted when list items areselected or unselected. However, in order to take advantage of thesesignals, you need to know <EM>which</EM> Tree widget they will beemitted by, and where to find the list of selected items.<P>This is a source of potential confusion. The best way to explain thisis that though all Tree widgets are created equal, some are more equalthan others. All Tree widgets have their own X window, and cantherefore receive events such as mouse clicks (if their TreeItems ortheir children don't catch them first!). However, to make<CODE>GTK_SELECTION_SINGLE</CODE> and <CODE>GTK_SELECTION_BROWSE</CODE> selectiontypes behave in a sane manner, the list of selected items is specificto the topmost Tree widget in a hierarchy, known as the "root tree".<P>Thus, accessing the <CODE>selection</CODE> field directly in an arbitraryTree widget is not a good idea unless you <EM>know</EM> it's the roottree. Instead, use the <CODE>GTK_TREE_SELECTION (Tree)</CODE> macro, whichgives the root tree's selection list as a GList pointer. Of course,this list can include items that are not in the subtree in question ifthe selection type is <CODE>GTK_SELECTION_MULTIPLE</CODE>.<P>Finally, the "select_child" (and "unselect_child", in theory) signalsare emitted by all trees, but the "selection_changed" signal is onlyemitted by the root tree. Consequently, if you want to handle the"select_child" signal for a tree and all its subtrees, you will haveto call gtk_signal_connect() for every subtree.<P><H2><A NAME="ss12.4">12.4 Tree Widget Internals</A></H2><P>The Tree's struct definition looks like this:<P><BLOCKQUOTE><CODE><PRE>struct _GtkTree{  GtkContainer container;  GList *children;    GtkTree* root_tree; /* owner of selection list */  GtkWidget* tree_owner;  GList *selection;  guint level;  guint indent_value;  guint current_indent;  guint selection_mode : 2;  guint view_mode : 1;  guint view_line : 1;};</PRE></CODE></BLOCKQUOTE><P>The perils associated with accessing the <CODE>selection</CODE> fielddirectly have already been mentioned. The other important fields ofthe struct can also be accessed with handy macros or class functions.<CODE>GTK_IS_ROOT_TREE (Tree)</CODE> returns a boolean value whichindicates whether a tree is the root tree in a Tree hierarchy, while<CODE>GTK_TREE_ROOT_TREE (Tree)</CODE> returns the root tree, an object oftype GtkTree (so, remember to cast it using <CODE>GTK_WIDGET (Tree)</CODE> ifyou want to use one of the gtk_widget_*() functions on it).<P>Instead of directly accessing the children field of a Tree widget,it's probably best to cast it using >tt/GTK_CONTAINER (Tree)/, andpass it to the gtk_container_children() function. This creates aduplicate of the original list, so it's advisable to free it up usingg_list_free() after you're done with it, or to iterate on itdestructively, like this:<P><BLOCKQUOTE><CODE><PRE>    children = gtk_container_children (GTK_CONTAINER (tree));    while (children) {      do_something_nice (GTK_TREE_ITEM (children->data));      children = g_list_remove_link (children, children);}</PRE></CODE></BLOCKQUOTE><P>The <CODE>tree_owner</CODE> field is defined only in subtrees, where itpoints to the TreeItem widget which holds the tree in question.The <CODE>level</CODE> field indicates how deeply nested a particular treeis; root trees have level 0, and each successive level of subtrees hasa level one greater than the parent level. This field is set onlyafter a Tree widget is actually mapped (i.e. drawn on the screen).<P><H3><A NAME="sec_Tree_Signals"></A> Signals</H3><P><BLOCKQUOTE><CODE><PRE>void selection_changed( GtkTree *tree );</PRE></CODE></BLOCKQUOTE><P>This signal will be emitted whenever the <CODE>selection</CODE> field of aTree has changed. This happens when a child of the Tree isselected or deselected.<P><BLOCKQUOTE><CODE><PRE>void select_child( GtkTree   *tree,                   GtkWidget *child );</PRE></CODE></BLOCKQUOTE><P>This signal is emitted when a child of the Tree is about to getselected. This happens on calls to gtk_tree_select_item(),gtk_tree_select_child(), on <EM>all</EM> button presses and calls togtk_tree_item_toggle() and gtk_item_toggle().  It may sometimes beindirectly triggered on other occasions where children get added to orremoved from the Tree.<P><BLOCKQUOTE><CODE><PRE>void unselect_child (GtkTree   *tree,                     GtkWidget *child);</PRE></CODE></BLOCKQUOTE><P>This signal is emitted when a child of the Tree is about to getdeselected. As of GTK 1.0.4, this seems to only occur on calls togtk_tree_unselect_item() or gtk_tree_unselect_child(), and perhaps onother occasions, but <EM>not</EM> when a button press deselects achild, nor on emission of the "toggle" signal by gtk_item_toggle().<P><H3><A NAME="sec_Tree_Functions"></A> Functions and Macros</H3><P><BLOCKQUOTE><CODE><PRE>guint gtk_tree_get_type( void );</PRE></CODE></BLOCKQUOTE><P>Returns the "GtkTree" type identifier.<P><BLOCKQUOTE><CODE><PRE>GtkWidget* gtk_tree_new( void );</PRE></CODE></BLOCKQUOTE><P>Create a new Tree object. The new widget is returned as a pointer to aGtkWidget object. NULL is returned on failure.<P><BLOCKQUOTE><CODE><PRE>void gtk_tree_append( GtkTree   *tree,                      GtkWidget *tree_item );</PRE></CODE></BLOCKQUOTE><P>Append a tree item to a Tree.<P><BLOCKQUOTE><CODE><PRE>void gtk_tree_prepend( GtkTree   *tree,                       GtkWidget *tree_item );</PRE></CODE></BLOCKQUOTE><P>Prepend a tree item to a Tree.<P><BLOCKQUOTE><CODE><PRE>void gtk_tree_insert( GtkTree   *tree,                      GtkWidget *tree_item,                      gint       position );</PRE></CODE></BLOCKQUOTE><P>Insert a tree item into a Tree at the position in the listspecified by <CODE>position.</CODE><P><BLOCKQUOTE><CODE><PRE>void gtk_tree_remove_items( GtkTree *tree,                            GList   *items );</PRE></CODE></BLOCKQUOTE><P>Remove a list of items (in the form of a GList *) from a Tree.Note that removing an item from a tree dereferences (and thus usually)destroys it <EM>and</EM> its subtree, if it has one, <EM>and</EM> allsubtrees in that subtree. If you want to remove only one item, youcan use gtk_container_remove().<P><BLOCKQUOTE><CODE><PRE>void gtk_tree_clear_items( GtkTree *tree,                           gint     start,

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?