greetings
I couldn't find any example of a gtk.TreeView fully reorderable per drag and drop,
neither in python nor in C. gtk.TreeView.set_reorderable() has many drawbacks, most
annoyingly those that one cannot "parent" an iter. but, as dnd in a gtk.TreeView is a
most demanded feature, I fiddled around some weeks. It turned out not an easy task for
a beginner in pygtk, python und programming as well.
well, the attachment is a working example. please send comments of all kinds -
suggestions on enhancement, error handling, style, etc.
what I don't like about it in particular is that a user has to gain experience how
to place the items. It seems to be more issues of gtk proper and lacking of
conventions for a uniform userinterface. maybe some sort of preview, where exactly the
row to move will ultimately be placed would be a handy solution.
walter
#!/usr/bin/env python
try:
import pygtk; pygtk.require("2.0")
except:
pass
import gtk
data = [[0,"zero"],[1,"one"],[2,"two"],[3,"three"],[4,"four"],[5,"five"],[6,"six"]]
class TreeDNDExample:
def checkSanity(self, model, iter_to_copy, target_iter):
path_of_iter_to_copy = model.get_path(iter_to_copy)
path_of_target_iter = model.get_path(target_iter)
if path_of_target_iter[0:len(path_of_iter_to_copy)] == path_of_iter_to_copy:
return False
else:
return True
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 onDragDataReceived(self, treeview, drag_context, x, y, selection, info,
eventtime):
path, pos = treeview.get_dest_row_at_pos(x, y)
model, iter_to_copy = treeview.get_selection().get_selected()
target_iter = model.get_iter(path)
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 __init__(self):
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.connect("delete_event", gtk.mainquit)
window.set_default_size(250, 350)
scrolledwin = gtk.ScrolledWindow()
scrolledwin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
window.add(scrolledwin)
model = gtk.TreeStore(int, str)
for item in data:
iter = model.append(None)
model.set(iter, 0, item[0], 1, item[1])
treeview = gtk.TreeView(model)
scrolledwin.add(treeview)
treeview.enable_model_drag_source(gtk.gdk.BUTTON1_MASK, [("example", 0, 0)],
gtk.gdk.ACTION_COPY)
treeview.enable_model_drag_dest([("example", 0, 0)], gtk.gdk.ACTION_COPY)
treeview.connect("drag_data_received", self.onDragDataReceived)
renderer = gtk.CellRendererText()
column = gtk.TreeViewColumn("Integer", renderer, text=0)
treeview.append_column(column)
column = gtk.TreeViewColumn("String", renderer, text=1)
treeview.append_column(column)
window.show_all()
def main():
gtk.main()
return 0
if __name__ == "__main__":
TreeDNDExample()
main()
_______________________________________________
pygtk mailing list [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/