本人用python为 treeview写了一种数据结构
Tofloor
poster avatar
vala2012
deepin
2013-04-14 00:20
Author
  1. #!coding:utf-8
  2. import gtk
  3. class TreeViewBase(gtk.Button):
  4.     def __init__(self):
  5.         self.nodes = Nodes()
  6.         self.nodes.connect("update-data", self.__nodes_update_data_event)
  7.       
  8.     def __nodes_update_data_event(self, nodes):
  9.         print "__nodes_update_data_event:", nodes.text
  10. class Nodes(list):
  11.     def __init__(self):
  12.         list.__init__(self)
  13.         self.this = None
  14.         self.__function_dict = {}
  15.     def add(self, text):
  16.         node = Node()
  17.         node.text = text
  18.         node.parent = self
  19.         if self.this:
  20.             node.leave  = self.this.leave + 1
  21.         node.connect("update-data", self.__node_update_data_event)
  22.         self.append(node)
  23.         self.emit("update-data", node)
  24.         return node
  25.     def __node_update_data_event(self, node):
  26.         self.emit("update-data", node)
  27.     def connect(self, event_name, function_point):
  28.         self.__function_dict[event_name] = function_point
  29.     def emit(self, event_name, *arg):
  30.         if self.__function_dict.has_key(event_name):
  31.             self.__function_dict[event_name](*arg)
  32. class Node(object):
  33.     def __init__(self):
  34.         self.__function_dict = {}
  35.         self.text  = ""
  36.         self.__pixbuf      = None
  37.         self.children = []
  38.         #
  39.         self.nodes = Nodes()
  40.         self.nodes.this = self
  41.         self.nodes.connect("update-data", self.__nodes_update_data_event)
  42.         #
  43.         self.parent = None # 获取当前树节点的夫节点.
  44.         self.leave  = 0    # 树的深度,不懂的看数据结构.
  45.         self.__last_node  = []   # 获取最后一个子树节点.
  46.         self.__first_node = []   # 获取树节点集合中的第一个子树节点.
  47.         self.__next_node  = []   # 获取下一个同级节点.
  48.         self.__prev_node  = []   # 获取上一个同级节点.
  49.         self.__index      = None # 获取树节点在树节点集合中的位置.
  50.         ####################
  51.         self.is_expanded = True # 是否展开状态.
  52.         self.is_selected = False # 是否选中状态.
  53.         self.is_editing  = False # 是否可编辑状态.
  54.         ####################
  55.         self.node_font   = None  # 字体.
  56.         self.next_visible_node = None # 获取下一个可见树节点.
  57.         self.is_visible  = True # 是否可见.
  58.     def __nodes_update_data_event(self, nodes):
  59.         self.emit("update-data", nodes)
  60.     def connect(self, event_name, function_point):
  61.         self.__function_dict[event_name] = function_point
  62.     def emit(self, event_name, *arg):
  63.         if self.__function_dict.has_key(event_name):
  64.             self.__function_dict[event_name](*arg)
  65.     def add_widget(self, child_widget):
  66.         self.children.append(child_widget)
  67.         self.emit()
  68.     @property
  69.     def last_node(self):
  70.     # 获取最后一个子树节点.
  71.         return self.__last_node
  72.     @last_node.getter
  73.     def last_node(self):
  74.         if self.nodes == []:
  75.             return None
  76.         else:
  77.             return self.nodes[len(self.nodes)-1]
  78.     @property
  79.     def first_node(self):
  80.     # 获取树节点集合中的第一个子树节点.
  81.         return self.__first_node
  82.     @first_node.getter
  83.     def first_node(self):
  84.         if self.nodes == []:
  85.             return None
  86.         else:
  87.             return self.nodes[0]
  88.     @property
  89.     def prev_node(self):
  90.         return self.__prev_node
  91.    
  92.     @prev_node.getter
  93.     def prev_node(self):
  94.         # 获取上一个同级节点.
  95.         if self.parent:
  96.             index = self.parent.index(self)
  97.             if index:
  98.                 node = self.parent[index - 1]
  99.                 self.__prev_node = node
  100.                 return self.__prev_node
  101.         return None
  102.     @property
  103.     def next_node(self):
  104.         # 获取下一个同级节点.
  105.         return self.__next_node
  106.     @next_node.getter
  107.     def next_node(self):
  108.         if self.parent:
  109.             index = self.parent.index(self)
  110.             if index < len(self.parent) - 1:
  111.                 node = self.parent[index + 1]
  112.                 self.__next_node = node
  113.                 return self.__next_node
  114.         return None
  115.     @next_node.deleter
  116.     def next_node(self):
  117.         del self.__next_node
  118.     @property
  119.     def index(self):
  120.         return self.__index
  121.     @index.getter
  122.     def index(self):
  123.         if self.parent:
  124.             _index = self.parent.index(self)
  125.             return _index
  126.         return None
  127.     @property
  128.     def pixbuf(self):
  129.         return self.__pixbuf
  130.     @pixbuf.getter
  131.     def pixbuf(self):
  132.         return self.__pixbuf
  133.     @pixbuf.setter
  134.     def pixbuf(self, pixbuf):
  135.         self.__pixbuf = pixbuf
  136.         self.emit()
  137.     @pixbuf.deleter
  138.     def pixbuf(self, pixbuf):
  139.         del self.__pixbuf
  140. if __name__ == "__main__":
  141.     win = gtk.Window(gtk.WINDOW_TOPLEVEL)
  142.     win.set_size_request(300, 300)
  143.     treeview_base = TreeViewBase()
  144.     treeview_base.set_size_request(1500, 15000)
  145.     scroll_win = gtk.ScrolledWindow()
  146.     #
  147.     node1 = treeview_base.nodes.add("root1")
  148.     node2 = treeview_base.nodes.add("root2")
  149.     node3 = treeview_base.nodes.add("root3")
  150.     node4 = treeview_base.nodes.add("root4")
  151.     '''
  152.     for i in range(1, 30000):
  153.         treeview_base.nodes.add("root" + str(i))
  154.     '''
  155.     node1_1 = node1.nodes.add("roo1-1")
  156.     node1_2 = node1.nodes.add("roo1-2")
  157.     node1_3 = node1.nodes.add("roo1-3")
  158.     node1_1_1 = node1_1.nodes.add("root1-1-1")
  159.     node1_4 = node1.nodes.add("roo1-4")
  160.     node1_5 = node1.nodes.add("roo1-5")
  161.     print node1.nodes[1].next_node.text
  162.     print node1.nodes[1].prev_node.text
  163.     #
  164.     #
  165.     scroll_win.add_with_viewport(treeview_base)
  166.     win.add(scroll_win)
  167.     win.show_all()
  168.     gtk.main()
Copy the Code

连接信号后,只要数据层更新,就能通知上层...
在界面层的代码中加入这个.
nodes = Nodes()
nodes.connect("update-data", ...........), 这样的方法类似于 C语言的 函数指针

nodes[0].nodes[3].is_expand = True ; 展开
nodes[0].nodes[3].is_expand = False ; 关闭展开.
nodes[0].nodes[3]. prev_node / next_node; 获取同级的兄弟节点(左右).
加上可以获取父亲节点,通过父亲节点去获取他的兄弟节点, 这样就可以将 leavel 为0的全部获取出来.
或者leave 为 3 的全部获取出来.

选区_012.png
选区_013.png
选区_014.png
我重载函数以后,我自绘....是不是很有味道.....  但数据更新和改变,删除的时候,如果不是重绘的区域,是不会进行重绘的...
哪怕后面删除了1万个数据,绘制层上的可视区域内没有这个数据在上面,是不进行重绘的. 重绘代表的是可视区域的,不是全部高度和宽度.
后续加入 改变一个数据的时候,只对这个可视区域的 这一个数据的区域进行重绘.
选区_015.png
完全高仿C#哦... ...

源码...
  1. from utils import get_match_parent
  2. #from utils import propagate_expose
  3. from utils import get_text_size
  4. from draw  import draw_text, draw_pixbuf
  5. from color import alpha_color_hex_to_cairo, color_hex_to_cairo
  6. import gtk
  7. from gtk import gdk
  8. import gobject
  9. import random
  10. def type_check(type_name, type_str):
  11.     return type(type_name).__name__ == type_str
  12. class TreeViewChild(object):
  13.     widget = None
  14.     x = 0
  15.     y = 0
  16.     w = 80
  17.     h = 40
  18. class TreeViewBase(gtk.Container):
  19.     def __init__(self):
  20.         gtk.Container.__init__(self)
  21.         self.__init_values()
  22.     def __init_values(self):
  23.         self.add_events(gtk.gdk.ALL_EVENTS_MASK)
  24.         #
  25.         self.header_height = 35
  26.         self.node_height   = 35
  27.         self.leave_width   = 20
  28.         #
  29.         self.children = []
  30.         #
  31.         self.paint_nodes_event = self.__paint_nodes_event
  32.         self.paint_nodes_background = self.__paint_nodes_background
  33.         #
  34.         self.__function_dict = {}
  35.         self.__nodes_list = []
  36.         self.nodes = Nodes()
  37.         self.nodes.connect("update-data", self.__nodes_update_data_event)
  38.         self.nodes.connect("added-data",  self.__nodes_added_data_event)
  39.         self.nodes.connect("remove-data", self.__nodes_remove_data_event)
  40.         self.nodes.connect("is-expanded", self.__nodes_is_expanded_event)
  41.         self.__init_values_columns()
  42.     def __nodes_update_data_event(self, node):
  43.         # 当有数据更新时,进行重绘.
  44.         # 判断是否在重绘的区域内,如果不是,只设置数据.
  45.         if self.tree_view_find_node_in_draw_area(node):
  46.             self.tree_view_queue_draw_area()
  47.     def __nodes_added_data_event(self, node):
  48.         # 添加数据更新树型结构的映射列表.
  49.         if node.parent == self.nodes:
  50.             self.__nodes_list.append(node)
  51.             self.__tree_view_set_add_size()
  52.       
  53.     def __nodes_is_expanded_event(self, node):
  54.         #print "__nodes_is_expanded_event", node.text
  55.         if node.is_expanded:
  56.             if node.nodes: # 判断是否有子节点.
  57.                 if node.leave: # 判断是不是根节点.
  58.                     if not node.parent.this.is_expanded: # 判断父亲节点是否已经展开了.
  59.                         node.parent.this.is_expanded = True
  60.                         for child_node in node.nodes:
  61.                             self.__nodes_add_data(child_node)
  62.                     else:
  63.                         for child_node in node.nodes:
  64.                             self.__nodes_add_data(child_node)
  65.                 else:
  66.                     for child_node in node.nodes:
  67.                         self.__nodes_add_data(child_node)
  68.         elif not node.is_expanded:
  69.             for flase_child_node in node.nodes:
  70.                 flase_child_node.is_expanded = False
  71.                 self.__nodes_remove_data(flase_child_node)
  72.     def __nodes_add_data(self, node):
  73.         parent = node.parent
  74.         node_to_parent_index = parent.index(node)
  75.         parent_to_list_index = self.__nodes_list.index(parent.this)
  76.         index = parent_to_list_index + node_to_parent_index + 1
  77.         self.__nodes_list.insert(index, node)
  78.         self.__tree_view_set_add_size()
  79.     def __nodes_remove_data(self, node):
  80.         index = self.__nodes_list.index(node)
  81.         self.__nodes_list.pop(index)
  82.         self.__tree_view_set_remove_size()
  83.     def __tree_view_set_add_size(self):
  84.         size = self.get_size_request()
  85.         self.set_size_request(size[0], size[1] + self.node_height)
  86.     def __tree_view_set_remove_size(self):
  87.         size = self.get_size_request()
  88.         self.set_size_request(size[0], size[1] - self.node_height)
  89.     def __nodes_remove_data_event(self, node):
  90.         # 当有数据删除时,更新映射列表.
  91.         print "remove............", node.text
  92.         if node in self.__nodes_list:
  93.             self.__nodes_list.remove(node)
  94.         # 判断删除的数据是否在重绘区域,如果不是,不进行重绘.
  95.         if self.tree_view_find_node_in_draw_area(node):
  96.             self.tree_view_queue_draw_area()
  97.     def __init_values_columns(self):
  98.         self.columns = []
  99.     def connect_event(self, event_name, function_potion):
  100.         self.__function_dict[event_name] = function_point
  101.     def emit(self, event_name, *arg):
  102.         if self.__function_dict.has_key(event_name):
  103.             self.__function_dict[event_name](*arg)
  104.         
  105.     def do_map(self):
  106.         print "do..map.."
  107.         gtk.Container.do_map(self)
  108.         self.set_flags(gtk.MAPPED)
  109.         #
  110.         self.window.show()
  111.     def do_umap(self):
  112.         print "do_map:"
  113.         gtk.Container.do_umap(self)
  114.         self.window.hide()
  115.     def do_realize(self):
  116.         print "do_realize..."
  117.         self.set_realized(True)
  118.         #
  119.         self.__init_window()
  120.         #
  121.         self.__init_children()
  122.         #
  123.         self.scroll_win = get_match_parent(self, ["ScrolledWindow"])
  124.         self.hadjustment = self.scroll_win.get_hadjustment()
  125.         self.vadjustment = self.scroll_win.get_vadjustment()
  126.         self.hadjustment.connect("value-changed", self.__list_view_adjustments_changed)
  127.         self.vadjustment.connect("value-changed", self.__list_view_adjustments_changed)
  128.         self.queue_resize()
  129.     def __list_view_adjustments_changed(self, adjustments):
  130.         self.tree_view_queue_draw_area()
  131.     def __init_window(self):
  132.         self.window = gdk.Window(
  133.             self.get_parent_window(),
  134.             window_type=gdk.WINDOW_CHILD,
  135.             x=self.allocation.x,
  136.             y=self.allocation.y,
  137.             width=self.allocation.width,
  138.             height=self.allocation.height,
  139.             colormap=self.get_colormap(),
  140.             wclass=gdk.INPUT_OUTPUT,
  141.             visual=self.get_visual(),
  142.             event_mask=(self.get_events()
  143.             | gtk.gdk.VISIBILITY_NOTIFY
  144.             | gdk.EXPOSURE_MASK
  145.             | gdk.SCROLL_MASK
  146.             | gdk.POINTER_MOTION_MASK
  147.             | gdk.ENTER_NOTIFY_MASK
  148.             | gdk.LEAVE_NOTIFY_MASK
  149.             | gdk.BUTTON_PRESS_MASK
  150.             | gdk.BUTTON_RELEASE_MASK
  151.             | gdk.KEY_PRESS_MASK
  152.             | gdk.KEY_RELEASE_MASK
  153.             ))
  154.         self.window.set_user_data(self)
  155.         self.style.set_background(self.window, gtk.STATE_NORMAL)
  156.     def __init_children(self):
  157.         for child in self.children:
  158.             print "child:", child.widget.set_parent_window(self.window)
  159.     def do_unrealize(self):
  160.         #
  161.         pass
  162.     def do_expose_event(self, e):
  163.         gtk.Container.do_expose_event(self, e)
  164.         if e.window == self.window:
  165.             cr = self.window.cairo_create()
  166.             start_index  = max(int(self.scroll_win.get_vadjustment().get_value() / self.node_height), 0)
  167.             end_index    = (start_index + (self.scroll_win.allocation.height) / self.node_height) + 1
  168.             y_padding = 0 + start_index * self.node_height
  169.             # draw background.
  170.             x = 0
  171.             y = 0 + start_index * self.node_height
  172.             w = self.scroll_win.allocation.width
  173.             h = self.scroll_win.allocation.height + self.node_height * 2
  174.             self.paint_nodes_background(cr, x, y, w, h)
  175.             # draw node.
  176.             for node in self.__nodes_list[start_index:end_index]:
  177.                 node_event = NodesEvent()
  178.                 node_event.cr = cr
  179.                 node_event.node = node
  180.                 node_event.x = 0
  181.                 node_event.y = y_padding
  182.                 node_event.w = self.scroll_win.allocation.width
  183.                 node_event.h = self.node_height #self.scroll_win.allocation.height
  184.                 '''
  185.                 node_event.draw_text = draw_text # 写成 set/get , 忽略 cr参数.
  186.                 node_event.draw_pixbuf = draw_pixbuf # 写成 set/get , 忽略 cr参数.
  187.                 '''
  188.                 self.paint_nodes_event(node_event)
  189.                 y_padding += self.node_height
  190.         #
  191.         return False
  192.     def __paint_nodes_background(self, cr, x, y, w, h):
  193.         cr.set_source_rgba(0, 0, 0, 0.85)
  194.         cr.rectangle(x, y, w, h)
  195.         cr.fill()
  196.     def __paint_nodes_event(self, node_event):
  197.         if node_event.node.leave == 0: # 根节点.
  198.             x = node_event.x + 10
  199.             if node_event.node.is_expanded:
  200.                 draw_text(node_event.cr,
  201.                           "-",
  202.                           node_event.x,
  203.                           node_event.y + get_text_size("+")[1]/2)
  204.             else:
  205.                 draw_text(node_event.cr,
  206.                           "+",
  207.                           node_event.x,
  208.                           node_event.y + get_text_size("+")[1]/2)
  209.         else:
  210.             x_padding = node_event.node.leave * self.leave_width
  211.             x = node_event.x + 10 + x_padding
  212.             if node_event.node.is_expanded:
  213.                 draw_text(node_event.cr,
  214.                           "*",
  215.                           node_event.x + x_padding,
  216.                           node_event.y + get_text_size("*")[1]/2)
  217.             else:
  218.                 if node_event.node.leave < 2:
  219.                     draw_text(node_event.cr,
  220.                               ">",
  221.                               node_event.x + x_padding,
  222.                               node_event.y + get_text_size(">")[1]/2)
  223.         draw_text(node_event.cr,
  224.                   node_event.node.text,
  225.                   x,
  226.                   node_event.y + get_text_size(node_event.node.text)[1]/2)
  227.     def tree_view_queue_draw_area(self):
  228.         self.scroll_win = get_match_parent(self, ["ScrolledWindow"])
  229.         if self.scroll_win:
  230.             start_index  = max(int(self.scroll_win.get_vadjustment().get_value() / self.node_height), 0)
  231.             end_index    = (start_index + (self.scroll_win.allocation.height) / self.node_height) + 1
  232.             w = self.scroll_win.allocation.width
  233.             h = self.scroll_win.allocation.height
  234.         else:
  235.             start_index = 0
  236.             end_index = self.allocation.height / self.allocation.height
  237.             w = self.allocation.width
  238.             h = self.allocation.height
  239.         x = 0
  240.         y = 0 + start_index * self.node_height
  241.         self.queue_draw_area(x, y, w, h)
  242.     def tree_view_find_node_in_draw_area(self, node):
  243.         if node in self.__nodes_list:
  244.             index = self.__nodes_list.index(node)
  245.             #
  246.             self.scroll_win = get_match_parent(self, "ScrolledWindow")
  247.             if self.scroll_win:
  248.                 start_index  = max(int(self.scroll_win.get_vadjustment().get_value() / self.node_height), 0)
  249.                 end_index    = (start_index + (self.scroll_win.allocation.height) / self.node_height) + 1
  250.             else:
  251.                 start_index = 0
  252.                 end_index = 0
  253.             if start_index <= index <= end_index:
  254.                 return True
  255.         return False
  256.     def do_motion_notify_event(self, e):
  257.         #print "do--mo--no--ev", e.x
  258.         if e.window == self.window:
  259.             index = int(e.y) / self.node_height
  260.             self.tree_view_queue_draw_area()
  261.         return False
  262.     def do_button_press_event(self, e):
  263.         #node.is_expanded = False #not node.is_expanded
  264.         #node.is_expanded = True
  265.         node = self.__nodes_list[int(e.y/self.node_height)]
  266.         node.is_expanded = not node.is_expanded
  267.         self.tree_view_queue_draw_area()
  268.         return False
  269.     def do_button_release_event(self, e):
  270.         #print "do_button_release_event..."
  271.         return False
  272.     def do_enter_notify_event(self, e):
  273.         #print "do_enter_notify_event..."
  274.         return False
  275.     def do_leave_notify_event(self, e):
  276.         #print "do_leave_notify_event..."
  277.         return False
  278.     def do_key_press_event(self, e):
  279.         print "do_key_press_event..."
  280.     def do_key_release_event(self, e):
  281.         print "do_key_release_event..."
  282.     def do_size_request(self, req):
  283.         '''
  284.         for child in self.children:
  285.             child.widget.size_request()
  286.         '''
  287.     def do_size_allocate(self, allocation):
  288.         print "do_size_allocate..."
  289.         gtk.Container.do_size_allocate(self, allocation)
  290.         '''
  291.         for child in self.children:
  292.             allocation = gdk.Rectangle()
  293.             allocation.x  = child.x
  294.             allocation.y  = child.y
  295.             allocation.width = child.w
  296.             allocation.height = child.h
  297.             child.widget.size_allocate(allocation)
  298.         '''
  299.         #
  300.         if self.get_realized():
  301.             self.window.move_resize(
  302.                     self.allocation.x,
  303.                     self.allocation.y,
  304.                     self.allocation.width,
  305.                     self.allocation.height)
  306.     def do_show(self):
  307.         gtk.Container.do_show(self)
  308.         #self.edit_entry.set_visible(False)
  309.     def do_destroy(self):
  310.         print "do_destroy..."
  311.     def do_forall(self, include_internals, callback, data):
  312.         '''
  313.         for child in self.children:
  314.             callback(child.widget, data)
  315.         '''
  316.         pass
  317.     def add_widget(self, child, x=0, y=0, w=0, h=0):
  318.         if self.window:
  319.             child.set_parent_window(self.window)
  320.         else:
  321.             child.set_parent(self)
  322.         tree_view_child = TreeViewChild()
  323.         tree_view_child.widget = child
  324.         tree_view_child.x = x
  325.         tree_view_child.y = y
  326.         tree_view_child.w = max(w, 80)
  327.         tree_view_child.h = max(h, self.node_height)
  328.         self.children.append(tree_view_child)
  329.     ############################################################
  330.     def delete(self, node): # 删除数据.
  331.         node.parent.delete(node)
  332.     def expanded_all(self): # 展开所有节点.
  333.         pass
  334. gobject.type_register(TreeViewBase)
  335. class NodesEvent(object):
  336.     def __init__(self):
  337.         self.cr = None
  338.         self.x  = 0
  339.         self.y  = 0
  340.         self.w  = 0
  341.         self.h  = 0
  342.         self.node = None
  343.         '''
  344.         self.draw_pixbuf
  345.         self.draw_text
  346.         '''
  347. class Nodes(list):
  348.     def __init__(self):
  349.         list.__init__(self)
  350.         self.this = None
  351.         self.__function_dict = {}
  352.     def add(self, text):
  353.         node = Node()
  354.         node.text = text
  355.         node.parent = self
  356.         if self.this:
  357.             node.leave  = self.this.leave + 1
  358.         node.connect("update-data", self.__node_update_data_event)
  359.         node.connect("added-data",  self.__node_added_data_event)
  360.         node.connect("remove-data", self.__node_remove_data_event)
  361.         node.connect("is-expanded", self.__Node_is_expanded_event)
  362.         self.append(node)
  363.         self.emit("added-data", node)
  364.         return node
  365.     def delete(self, node):
  366.         self.emit("remove-data", node)
  367.         self.remove(node)
  368.         for child_node in node.nodes[:]:
  369.             node.nodes.delete(child_node)
  370.     def __node_update_data_event(self, node):
  371.         self.emit("update-data", node)
  372.     def __node_added_data_event(self, node):
  373.         self.emit("added-data", node)
  374.     def __node_remove_data_event(self, node):
  375.         self.emit("remove-data", node)
  376.     def __Node_is_expanded_event(self, node):
  377.         self.emit("is-expanded", node)
  378.     def connect(self, event_name, function_point):
  379.         self.__function_dict[event_name] = function_point
  380.     def emit(self, event_name, *arg):
  381.         if self.__function_dict.has_key(event_name):
  382.             self.__function_dict[event_name](*arg)
  383. class Node(object):
  384.     def __init__(self):
  385.         self.__function_dict = {}
  386.         self.text  = ""
  387.         #self.sub_items = SubItems()
  388.         self.__pixbuf      = None
  389.         self.children = []
  390.         #
  391.         self.nodes = Nodes()
  392.         self.nodes.this = self
  393.         self.nodes.connect("update-data", self.__nodes_update_data_event)
  394.         self.nodes.connect("added-data",  self.__nodes_added_data_event)
  395.         self.nodes.connect("remove-data", self.__nodes_remove_data_event)
  396.         self.nodes.connect("is-expanded", self.__nodes_is_expanded_event)
  397.         #
  398.         self.parent = None # 获取当前树节点的夫节点.
  399.         self.leave  = 0    # 树的深度,不懂的看数据结构.
  400.         self.__last_node  = []   # 获取最后一个子树节点.
  401.         self.__first_node = []   # 获取树节点集合中的第一个子树节点.
  402.         self.__next_node  = []   # 获取下一个同级节点.
  403.         self.__prev_node  = []   # 获取上一个同级节点.
  404.         self.__index      = None # 获取树节点在树节点集合中的位置.
  405.         ####################
  406.         self.__is_expanded = False # 是否展开状态.
  407.         self.is_selected = False # 是否选中状态.
  408.         self.is_editing  = False # 是否可编辑状态.
  409.         ####################
  410.         self.node_font   = None  # 字体.
  411.         self.next_visible_node = None # 获取下一个可见树节点.
  412.         self.is_visible  = True # 是否可见.
  413.     def __nodes_update_data_event(self, nodes):
  414.         self.emit("update-data", nodes)
  415.     def __nodes_added_data_event(self, nodes):
  416.         self.emit("added-data", nodes)
  417.     def __nodes_remove_data_event(self, nodes):
  418.         self.emit("remove-data", nodes)
  419.     def __nodes_is_expanded_event(self, nodes):
  420.         self.emit("is-expanded", nodes)
  421.     def connect(self, event_name, function_point):
  422.         self.__function_dict[event_name] = function_point
  423.     def emit(self, event_name, *arg):
  424.         if self.__function_dict.has_key(event_name):
  425.             self.__function_dict[event_name](*arg)
  426.     '''
  427.     def add_widget(self, child_widget):
  428.         self.children.append(child_widget)
  429.     '''
  430.     @property
  431.     def is_expanded(self):
  432.         return self.__is_expanded
  433.     @is_expanded.setter
  434.     def is_expanded(self, check):
  435.         # 判断 is_expanded 不能相同 却 nodes不为空.
  436.         if self.__is_expanded != check and self.nodes:
  437.             self.__is_expanded = check
  438.             self.emit("is-expanded", self)
  439.     @is_expanded.getter
  440.     def is_expanded(self):
  441.         return self.__is_expanded
  442.     @property
  443.     def text(self):
  444.         return self.__text
  445.     @text.setter
  446.     def text(self, text):
  447.         self.__text = text
  448.         self.emit("update-data", self)
  449.     @text.getter
  450.     def text(self):
  451.         return self.__text
  452.     @property
  453.     def last_node(self):
  454.     # 获取最后一个子树节点.
  455.         return self.__last_node
  456.     @last_node.getter
  457.     def last_node(self):
  458.         if self.nodes == []:
  459.             return None
  460.         else:
  461.             return self.nodes[len(self.nodes)-1]
  462.     @property
  463.     def first_node(self):
  464.     # 获取树节点集合中的第一个子树节点.
  465.         return self.__first_node
  466.     @first_node.getter
  467.     def first_node(self):
  468.         if self.nodes == []:
  469.             return None
  470.         else:
  471.             return self.nodes[0]
  472.     @property
  473.     def prev_node(self):
  474.         return self.__prev_node
  475.    
  476.     @prev_node.getter
  477.     def prev_node(self):
  478.         # 获取上一个同级节点.
  479.         if self.parent:
  480.             index = self.parent.index(self)
  481.             if index:
  482.                 node = self.parent[index - 1]
  483.                 self.__prev_node = node
  484.                 return self.__prev_node
  485.         return None
  486.     @property
  487.     def next_node(self):
  488.         # 获取下一个同级节点.
  489.         return self.__next_node
  490.     @next_node.getter
  491.     def next_node(self):
  492.         if self.parent:
  493.             index = self.parent.index(self)
  494.             if index < len(self.parent) - 1:
  495.                 node = self.parent[index + 1]
  496.                 self.__next_node = node
  497.                 return self.__next_node
  498.         return None
  499.     @next_node.deleter
  500.     def next_node(self):
  501.         del self.__next_node
  502.     @property
  503.     def index(self):
  504.         return self.__index
  505.     @index.getter
  506.     def index(self):
  507.         if self.parent:
  508.             _index = self.parent.index(self)
  509.             return _index
  510.         return None
  511.     @property
  512.     def pixbuf(self):
  513.         return self.__pixbuf
  514.     @pixbuf.getter
  515.     def pixbuf(self):
  516.         return self.__pixbuf
  517.     @pixbuf.setter
  518.     def pixbuf(self, pixbuf):
  519.         self.__pixbuf = pixbuf
  520.         #self.emit()
  521.     @pixbuf.deleter
  522.     def pixbuf(self, pixbuf):
  523.         del self.__pixbuf
  524. if __name__ == "__main__":
  525.     def test_paint_nodes_event(e):
  526.         if e.node.leave == 0: # 根节点.
  527.             draw_text(e.cr,
  528.                       e.node.text,
  529.                       e.x + e.w/2 - get_text_size(e.node.text)[0]/2,
  530.                       e.y + e.h/2 - get_text_size(e.node.text)[1]/2)
  531.             e.cr.set_source_rgba(1, 1, 1, 1.0)
  532.             e.cr.rectangle(e.x, e.y, e.w, e.h)
  533.             e.cr.stroke()
  534.         else:
  535.             pixbuf = gtk.gdk.pixbuf_new_from_file("logo.png")
  536.             pixbuf = pixbuf.scale_simple(e.h, e.h, gtk.gdk.INTERP_BILINEAR)
  537.             draw_pixbuf(e.cr, pixbuf, e.x + e.w/2 - pixbuf.get_width()/2 + e.node.leave * e.h, e.y)
  538.             draw_text(e.cr,
  539.                       e.node.text,
  540.                       e.x + e.w/2 - get_text_size(e.node.text)[1]/2 + pixbuf.get_width() + e.node.leave * e.h,
  541.                       e.y + e.h/2 - get_text_size(e.node.text)[1]/2)
  542.         
  543.     win = gtk.Window(gtk.WINDOW_TOPLEVEL)
  544.     win.set_size_request(300, 300)
  545.     treeview_base = TreeViewBase()
  546.     treeview_base.paint_nodes_event = test_paint_nodes_event
  547.     scroll_win = gtk.ScrolledWindow()
  548.     #
  549.     node1 = treeview_base.nodes.add("小学")
  550.     node2 = treeview_base.nodes.add("初中")
  551.     node3 = treeview_base.nodes.add("高中")
  552.     node4 = treeview_base.nodes.add("大学")
  553.     node5 = treeview_base.nodes.add("社会")
  554.     for i in range(1, 10000):
  555.         treeview_base.nodes.add("test" + str(i))
  556.     print treeview_base.nodes[9999].text
  557.     for i in range(1, 7):
  558.         node1.nodes.add(str(i) + "年级")
  559.         node1.nodes[0].nodes.add("1年级(" + str(i) + ")班")
  560.     node1.nodes[0].nodes[0].nodes.add("小明")
  561.     node1.nodes[0].nodes[0].nodes.add("小王")
  562.     node1.nodes[0].nodes[0].nodes.add("小张")
  563.     node1.nodes[0].nodes[0].nodes.add("小红")
  564.     node1.nodes[0].nodes[0].is_expanded = True
  565.     for i in range(1, 4):
  566.         node2.nodes.add("初" + str(i))
  567.         node3.nodes.add("高" + str(i))
  568.         node4.nodes.add("大" + str(i))
  569.         node4.nodes[0].nodes.add("软件班级ZB4890" + str(i))
  570.     #
  571.     scroll_win.add_with_viewport(treeview_base)
  572.     win.add(scroll_win)
  573.     win.show_all()
  574.     gtk.main()
Copy the Code
Reply Favorite View the author
All Replies
go2012
deepin
2013-04-14 07:54
#1
不错,顶楼主,果然是好东西... ...
Reply View the author
java2012
deepin
2013-04-14 07:55
#2
不错,顶楼主,要发扬广大哈,楼主继续努力...
Reply View the author
cxbii
deepin
2013-04-14 22:54
#3
lz好厉害。。。。我顶你。。
Reply View the author
vala2012
deepin
2013-04-15 02:03
#4
lz好厉害。。。。我顶你。。
哈哈哈,坛主好人一枚
Reply View the author
cxbii
deepin
2013-04-15 04:56
#5
[quote]lz好厉害。。。。我顶你。。
哈哈哈,坛主好人一枚[/quote]
:? 好人卡么
我也要学编程。。
Reply View the author
vala2012
deepin
2013-04-15 09:29
#6
[quote][quote]lz好厉害。。。。我顶你。。
哈哈哈,坛主好人一枚[/quote]
:? 好人卡么
我也要学编程。。[/quote]
学吧,编程一点都不难, 开源这么多代码, 看看就会拉! 不行照抄一个, 支持你.... ...!!
难的是搞游戏引擎的人(数学物理要牛).... .. 不是一般人能搞的.. 还有搞协议的...
Reply View the author