[pygtk] PyGtk drag n drop and reparenting

acano@systec.com acano@systec.com
Tue, 18 Jul 2000 09:16:51 -0400


On Tue, 18 Jul 2000 09:29:47 +0200, MOULET Xavier FTRD/DMR/ISS <xavier.moulet@rd.francetelecom.fr> wrote:
> Hello everybody. As I told in my last email, I spennt another night on this
> and could not find what was causing any trouble. The following program
> should let me drag a node over another, and then the dragged node becomes a
> child of the other one. drag_data_set were methods of my node object, which
> led to many segfaults. Now, I placed them away but I still have problems.
> 
> I pass a string to look up at which node is passed, as you can only pass
> strings in a drag data I think. My problem is, the dragged data disappears,
> the other ones remain as they were and a gtk warning appears. What do I
> wrong ? can someone cast some light on me ?
> 
> -- Beginning of the "program"
> 
> 
> # Sample gnome-python prog
> 
> # Imports
> from gtk import *
> import GDK
> import GTK
> 
> 	
> def drag_data_get (widget,context,data,info,time,user) :
> 	data.set(data.target,123,user)
> 
> def drag_data_rec (widget,context,x,y,data,info,time,user) :
> 	if user == data.data :
> 		# drags over myself : do nothing
> 		widget.drag_finish(context,FALSE,FALSE,time)
> 	else :	
> 		noeud = app.nodes[data.data]       # Look up the dragged
> (incoming) node
> 		noeud.gtknode.drag_finish(context,TRUE,TRUE,time)
> 
> 		me = app.nodes[user] # who has it been dragged to ? (whoami
> ?)
> 		
> 		# if no tree, create one		
> 		if me.subtree==None :
> 			me.subtree = GtkTree()
> 			me.subtree.show()
> 			noeud.gtknode.set_subtree(me.subtree)
> 			
> 		noeud.gtknode.reparent(me.subtree)
> 		noeud.gtknode.show()

I think you might have the source and destination mixed up.

try ->
		# if no tree, create one
		if me.subtree == None:
			me.subtree = GtkTree ()
			me.subtree.show ()
			#noeud.gtknode.set_subtree(me.subtree)
			widget.set_subtree (me.subtree) # widget is where you are
											# dragging to

		#noeud.gtknode.reparent(me.subtree)
		#noeud.gtknode.show()
		
		# remember to remove the item you drag, that caused the
		# gtk warning.
		# noeud.gtknode is the item you are dragging, and 'tree' is
		# the original tree you created in App.__init__()
		global tree
		tree.remove_item (noeud.gtknode)	
		me.subtree.append (noeud.gtknode)


there's also some changes to class App ->

> # my main node class.
> class UI_Node :
> 
>        def __init__ (self, label="Unknown") :
> 		self.label = label
> 
> 		self.subtree = None
> 
> 		self.gtknode = GtkTreeItem(self.label)
> 		self.gtknode.show()
> 				
> 		# Drag interface
> 		target = [('GLOOPNODE',0,-1)]
> 	
> self.gtknode.drag_source_set(GDK.BUTTON1_MASK,target,GDK.ACTION_COPY)
> 	
> self.gtknode.connect("drag_data_get",drag_data_get,self.label)
> 		
> 		# Drop interface
> 	
> self.gtknode.connect("drag_data_received",drag_data_rec,self.label)
> 	
> self.gtknode.drag_dest_set(GTK.DEST_DEFAULT_ALL,target,GDK.ACTION_COPY)
> 		
> class App :
> 	def __init__(self):
>  		self.window = GtkWindow();
> 		self.window.connect("destroy",mainquit)
> 
		
		global tree

		
> 		self.tree = GtkTree()

		tree = self.tree


> 		self.window.add(self.tree)
> 		self.window.show_all() 		
> 
> 		self.nodes = {} # Nodes : a dictonnary, keys are names of
> nodes, then node is given
> 
> 
> 	def append(self,node) :
>       		self.nodes[node.label] = node 
> 		self.tree.append(node.gtknode)		
> 
> 	def main (self) :
> 		self.append(UI_Node("foo1"))
> 		self.append(UI_Node("foo2"))
> 		self.append(UI_Node("foo3"))
> 		self.append(UI_Node("foo4"))
> 		
> 		
> if __name__ == '__main__' :
> 	global app
> 	app = App()
> 	app.main()
> 
> 	mainloop()
> 	
> # dragging a node to another makes : 
> # Gtk-CRITICAL **: file gtkwidget.c: line 2933
> (gtk_widget_reparent_container_child): assertion `client_data != NULL'
> failed.
> # and the dragged widget disappears.
> 
> _______________________________________________
> pygtk mailing list   pygtk@daa.com.au
> http://www.daa.com.au/mailman/listinfo/pygtk
>