[pygtk] PyGtk drag n drop and reparenting

MOULET Xavier FTRD/DMR/ISS xavier.moulet@rd.francetelecom.fr
Tue, 18 Jul 2000 09:29:47 +0200


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()
# 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)

		self.tree = GtkTree()
		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.