Advertisement
Uno-Dan

Treeview

Sep 9th, 2019
296
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.84 KB | None | 0 0
  1. class Treeview(Base, ttk.Treeview):
  2.     def __init__(self, parent, key, **kwargs):
  3.         Base.__init__(self, parent, key, **kwargs)
  4.         columns = dict(kwargs.get('settings', ())).get('columns', ())
  5.         headings = dict(kwargs.get('settings', ())).get('headings', ())
  6.         ttk.Treeview.__init__(self, parent, columns=tuple(range(1, len(columns))), **self.options_args)
  7.         # self['columns'] = range(1, len(columns))
  8.         self.column_sort = {}
  9.  
  10.         for index, column in enumerate(columns):
  11.             self.column(f'#{index}', **dict(column))
  12.  
  13.         for index, heading in enumerate(headings):
  14.             self.column_sort[f'#{index}'] = False
  15.             self.heading(f'#{index}', **dict(heading))
  16.  
  17.         self.grid(**self.grid_args)
  18.         parent.winfo_toplevel().style.configure("Treeview", fieldbackground="black")
  19.  
  20.         def on_click(event):
  21.             region = self.identify("region", event.x, event.y)
  22.             if region == "heading":
  23.                 column_number = self.identify_column(event.x)
  24.                 print(111, column_number)
  25.                 if self.column_sort[column]:
  26.                     self.column_sort[column] = False
  27.                 else:
  28.                     self.column_sort[column] = True
  29.  
  30.                 self.sortit(column_number, self.column_sort[column])
  31.  
  32.             if region == "separator":
  33.                 column_number = self.identify_column(event.x)
  34.                 self.separator_double_click(column_number)
  35.  
  36.         self.bind("<Button-1>", on_click)
  37.  
  38.     def __str__(self):
  39.         return str(self.get_nodes())
  40.  
  41.     def cut(self):
  42.         self.copy()
  43.         self.remove()
  44.  
  45.     def copy(self):
  46.         data = self.get_nodes(self.selection()[0])
  47.         if data:
  48.             self.winfo_toplevel().clipboard_clear()
  49.             self.winfo_toplevel().clipboard_append(str(data))
  50.  
  51.     def paste(self):
  52.         try:
  53.             data = literal_eval(self.winfo_toplevel().clipboard_get())
  54.             self.populate(self.selection()[0], **data)
  55.         except ValueError:
  56.             pass
  57.  
  58.     def sortit(self, col, reverse):
  59.         col = col.lstrip('#')
  60.  
  61.         column_data = []
  62.         for k in self.get_children():
  63.             column_data.append(k)
  64.         column_data.sort(reverse=reverse)
  65.  
  66.         for index, k in enumerate(column_data):
  67.             self.move(k, '', index)
  68.  
  69.         # reverse sort next time
  70.         self.heading(col, command=lambda _col=col: self.sortit(_col, not reverse))
  71.  
  72.     def add(self, parent, index=tk.END, **kwargs):
  73.         try:
  74.             self.insert(parent, index, **kwargs)
  75.         except TclError as err:
  76.             if 'already exists' in str(err):
  77.                 messagebox.showerror(
  78.                     title='Create Project',
  79.                     message=f'The name you entered," {kwargs.get("text", "")}" already exists. '
  80.                             f'Choose another name and try again.'
  81.                     )
  82.  
  83.     def append(self, parent, **kwargs):
  84.         self.add(parent, tk.END, **kwargs)
  85.  
  86.     def remove(self):
  87.         selection = self.selection()[0]
  88.  
  89.         _prev = self.prev(selection)
  90.         _next = self.next(selection)
  91.  
  92.         self.delete(selection)
  93.         if _next:
  94.             self.selection_set(_next)
  95.         else:
  96.             _next = '_'.join(selection.split('_')[:-1])
  97.             if not self.next(_next):
  98.                 _next = '_'.join(_next.split('_')[:-1])
  99.                 if not self.next(_next):
  100.                     self.select_tail()
  101.             if self.next(_next):
  102.                 self.selection_set(self.next(_next))
  103.  
  104.     def populate(self, parent, index=tk.END, **data):
  105.         _cache = Cache(**data)
  106.  
  107.         def walk(_cfg, iid, _parent):
  108.             attrs = {}
  109.             cfg = deepcopy(_cfg)
  110.  
  111.             for _key, value in _cfg.items():
  112.                 if not isinstance(value, dict):
  113.                     attrs[_key] = cfg.pop(_key)
  114.  
  115.             iid = f'{_parent}_{iid.split("_")[-1]}'.lstrip('_')
  116.             self.insert(_parent, index, iid=iid, **attrs)
  117.  
  118.             for _key, value in cfg.items():
  119.                 walk(value, f'{_key.split("_")[-1]}', iid)
  120.  
  121.         for key, node in data.items():
  122.             walk(node, key, parent)
  123.  
  124.     def get_nodes(self, uri=None):
  125.         data = Cache()
  126.  
  127.         def walk(*args):
  128.             parent = args[0]
  129.             children = args[1]
  130.  
  131.             for child in children:
  132.                 _uri = f'{parent}/{child}'
  133.                 data.set(_uri, **self.item(child))
  134.  
  135.                 child_children = self.get_children(child)
  136.  
  137.                 if child_children:
  138.                     walk(_uri, child_children)
  139.  
  140.         if uri:
  141.             data.set(uri, **self.item(uri))
  142.             walk(uri, self.get_children(uri))
  143.         else:
  144.             for uri in self.get_children():
  145.                 data.set(uri, **self.item(uri))
  146.                 walk(uri, self.get_children(uri))
  147.  
  148.         return deepcopy(data.get())
  149.  
  150.     def separator_double_click(self, column):
  151.         _cache = Cache(**self.get_nodes())
  152.  
  153.         _frame = ttk.Frame(self.winfo_toplevel())
  154.  
  155.         def walk(children, _maximum=0):
  156.  
  157.             for child in children:
  158.                 if not self.item(child)['open']:
  159.                     continue
  160.                 if self.get_children(child):
  161.  
  162.                     for item in self.get_children(child):
  163.                         parts = item.split('_')
  164.                         _size = 20 * len(parts)
  165.                         if column == '#0':
  166.                             text = self.item(item).get('text', '')
  167.                         else:
  168.                             text = self.item(item).get('values', '')[int(column.lstrip('#'))]
  169.  
  170.                         x = tk.Label(_frame, text=text)
  171.                         x.grid()
  172.                         _frame.update_idletasks()
  173.                         _size += x.winfo_width()
  174.  
  175.                         if _size > _maximum:
  176.                             _maximum = _size
  177.                     return walk(self.get_children(child), _maximum)
  178.  
  179.             return _maximum
  180.  
  181.         maximum = 0
  182.         for uri in self.get_children():
  183.             size = walk(self.get_children(uri), maximum)
  184.             if size > maximum:
  185.                 maximum = size
  186.  
  187.         print(maximum)
  188.         if self.column(column)['width'] == maximum:
  189.             self.column(column, width=3)
  190.         else:
  191.             self.column(column, width=maximum)
  192.  
  193.     def select_tail(self):
  194.         def walk(children):
  195.             if children:
  196.                 child = list(children).pop()
  197.                 if self.item(child)['open']:
  198.                     walk(self.get_children(child))
  199.                     if len(self.get_children(child)) == 0:
  200.                         self.selection_set(child)
  201.                 else:
  202.                     self.selection_set(child)
  203.  
  204.         walk(self.get_children())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement