169 lines
6.8 KiB
Python
Executable File
169 lines
6.8 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# [SNIPPET_NAME: gtk3 treeview using a treestore]
|
|
# [SNIPPET_CATEGORIES: gtk3]
|
|
# [SNIPPET_TAGS: widgets, gtk3]
|
|
# [SNIPPET_DESCRIPTION: GTK3 treeview in treestore, show the data in a expandable hierarchy]
|
|
# [SNIPPET_AUTHOR: Oliver Marks ]
|
|
# [SNIPPET_LICENSE: GPL]
|
|
from gi.repository import Gdk, Gtk, GLib
|
|
|
|
#http://jason.zwolak.org/technoblog/2010/08/drag-and-drop-with-gtk2-and-perl/
|
|
class application_gui:
|
|
"""Tutorial 10 text input, display a treeview in expandable tree format."""
|
|
count = 0
|
|
|
|
def __init__(self):
|
|
#load in our glade interface
|
|
xml = Gtk.Builder()
|
|
xml.add_from_file('tut10.glade')
|
|
|
|
#grab our widget using get_object this is the name of the widget from glade, window1 is the default name
|
|
self.window = xml.get_object('window1')
|
|
self.text = xml.get_object('entry1')
|
|
|
|
#load our widgets from the glade file
|
|
self.widgets = {}
|
|
self.widgets['treeview'] = xml.get_object('treeview1')
|
|
treeview(self.widgets['treeview'], self.text)
|
|
|
|
|
|
#connect to events, in this instance just quit our application
|
|
self.window.connect('delete_event', Gtk.main_quit)
|
|
self.window.connect('destroy', lambda quit: Gtk.main_quit())
|
|
|
|
#show the window else there is nothing to see :)
|
|
self.window.show()
|
|
|
|
|
|
class treeview:
|
|
treeview = None
|
|
treemodel = None
|
|
|
|
selected = 'workspace'
|
|
|
|
def __init__(self, treeview, entry):
|
|
self.entry = entry
|
|
self.treeview = treeview
|
|
|
|
self.treeview.connect('row-activated', self.selection)
|
|
self.treeview.connect('button_press_event', self.mouse_click)
|
|
|
|
#self.fixed_area.drag_dest_set(Gtk.DestDefaults.ALL, [], Gdk.DragAction.MOVE)
|
|
self.treeview.enable_model_drag_source(Gdk.ModifierType.BUTTON1_MASK, [("example", 0, 0)], Gdk.DragAction.COPY)
|
|
self.treeview.enable_model_drag_dest([("example", 0, 0)], Gdk.DragAction.COPY)
|
|
#treeview.enable_model_drag_source(gtk.gdk.BUTTON1_MASK, [("example", 0, 0)], Gdk.DragAction.ACTION_COPY)
|
|
#treeview.enable_model_drag_dest([("example", 0, 0)], gtk.gdk.ACTION_COPY)
|
|
|
|
self.treeview.connect("drag_data_received", self.onDragDataReceived)
|
|
|
|
|
|
#create a storage model in this case a treemodel
|
|
self.treemodel = Gtk.TreeStore(str)
|
|
self.treeview.set_model(self.treemodel)
|
|
|
|
#add columns usually only one in case of the treeview
|
|
column = Gtk.TreeViewColumn("Objects")
|
|
self.treeview.append_column(column)
|
|
|
|
#add in a text renderer so we can see the items we add
|
|
cell = Gtk.CellRendererText()
|
|
column.pack_start(cell, False)
|
|
column.add_attribute(cell, "text", 0)
|
|
|
|
self.populate()
|
|
self.menu()
|
|
|
|
#~ def iterCopy(self, treeview, model, iter_to_copy, target_iter, pos):
|
|
#~
|
|
#~ data_column_0 = model.get_value(iter_to_copy, 0)
|
|
#~ data_column_1 = model.get_value(iter_to_copy, 1)
|
|
#~ if (pos == gtk.TREE_VIEW_DROP_INTO_OR_BEFORE) or (pos == gtk.TREE_VIEW_DROP_INTO_OR_AFTER):
|
|
#~ new_iter = model.prepend(target_iter, None)
|
|
#~ elif pos == gtk.TREE_VIEW_DROP_BEFORE:
|
|
#~ new_iter = model.insert_before(None, target_iter)
|
|
#~ elif pos == gtk.TREE_VIEW_DROP_AFTER:
|
|
#~ new_iter = model.insert_after(None, target_iter)
|
|
#~ model.set_value(new_iter, 0, data_column_0)
|
|
#~ model.set_value(new_iter, 1, data_column_1)
|
|
#~ if model.iter_has_child(iter_to_copy):
|
|
#~ for i in range(0, model.iter_n_children(iter_to_copy)):
|
|
#~ next_iter_to_copy = model.iter_nth_child(iter_to_copy, i)
|
|
#~ self.iterCopy(treeview, model, next_iter_to_copy, new_iter, gtk.TREE_VIEW_DROP_INTO_OR_BEFORE)
|
|
|
|
def walk(self, treeiter):
|
|
if model.iter_has_child(treeiter):
|
|
for i in range(0, model.iter_n_children(treeiter)):
|
|
yield model.iter_nth_child(treeiter, i)
|
|
|
|
def onDragDataReceived(self, treeview, drag_context, x, y, selection, info, eventtime):
|
|
"""on data recieve we remove the item and insert in the new location, the insert location must have the same depth"""
|
|
model, iter_source = treeview.get_selection().get_selected()
|
|
source_path = model.get_path(iter_source)
|
|
print 'source iter path %s' % source_path
|
|
destination_path, pos = treeview.get_dest_row_at_pos(x, y)
|
|
print 'destination iter path %s' % destination_path
|
|
|
|
source_iter = model.get_iter(source_path)
|
|
destination_iter = model.get_iter(destination_path)
|
|
#model.remove(source_iter)
|
|
print source_iter
|
|
|
|
print destination_iter
|
|
print 'insert'
|
|
model.move_after(source_iter, destination_iter)
|
|
#self.append_tree(destination_iter)
|
|
#~ if self.checkSanity(model, iter_to_copy, target_iter):
|
|
#~ self.iterCopy(treeview, model, iter_to_copy, target_iter, pos)
|
|
#~ drag_context.finish(gtk.TRUE, gtk.TRUE, eventtime)
|
|
#~ treeview.expand_all()
|
|
#~ else:
|
|
#~ drag_context.finish(gtk.FALSE, gtk.FALSE, eventtime)
|
|
|
|
def populate(self):
|
|
self.treemodel.clear()
|
|
#populate the treeview with a largish tree
|
|
for item1 in range(0, 5):
|
|
iter_level_1 = self.append_tree('Item ' + str(item1))
|
|
for item2 in range(0, 5):
|
|
iter_level_2 = self.append_tree('Sub Item ' + str(item2), iter_level_1)
|
|
for item3 in range(0, 5):
|
|
self.append_tree('Sub Sub Item ' + str(item3), iter_level_2)
|
|
|
|
def append_tree(self, name, parent=None):
|
|
"""
|
|
append to the treeview if parent is null append to root level.
|
|
if parent is a valid iter (possibly returned from previous append) then append under the parent
|
|
"""
|
|
myiter = self.treemodel.insert_after(parent, None)
|
|
self.treemodel.set_value(myiter, 0, name)
|
|
return myiter
|
|
|
|
def menu(self):
|
|
"""
|
|
popover menu shown on right clicking a treeview item.
|
|
"""
|
|
self.treeview_menu = Gtk.Menu()
|
|
for item in range(0, 5):
|
|
menu_item = Gtk.MenuItem("Menu " + str(item))
|
|
self.treeview_menu.append(menu_item)
|
|
|
|
def mouse_click(self, tv, event):
|
|
if event.button == 3:
|
|
# right mouse button pressed popup the menu
|
|
self.treeview_menu.show_all()
|
|
self.treeview_menu.popup(None, None, None, None, 1, 0)
|
|
|
|
def selection(self, tv, treepath, tvcolumn):
|
|
"""
|
|
on double click get the value of the item we clicked
|
|
"""
|
|
model = tv.get_model()
|
|
treeiter = model.get_iter(treepath)
|
|
self.selected = model.get_value(treeiter, 0)
|
|
self.entry.set_text(self.selected)
|
|
|
|
|
|
|
|
application = application_gui()
|
|
Gtk.main()
|