Differences between revisions 12 and 13
Revision 12 as of 2005-02-20 11:45:45
Size: 10840
Editor: host124-135
Comment: updated the link to the other DnD example with tree control
Revision 13 as of 2008-03-11 10:50:28
Size: 10840
Editor: localhost
Comment: converted to 1.6 markup
No differences found!

Introduction

  • Drag and drop support within wxPython is a conversation between a "drop source" and a "drop target". The conversation is accomplished by sharing a "data object" which includes certain pieces of metadata (primarily the data types available from the drop source) as well as the actual shared data.

What Objects are Involved

  • Source window -- Interprets an event as the beginning of a new drag-and-drop request. Instantiates a new drop source

    and triggers the drag-and-drop sequence by calling DoDragDrop on the drop source object. Responds to the result code of the drag-and-drop sequence (move/copy/cancel/fail).

  • wxDropSource -- Provides common functionality for drag-and-drop source windows (UI interactions, data object storage)

  • Destination window -- Advertises acceptable data types by

    calling SetDropTarget with a configured drop target object.

  • wxDropTarget -- Responds to various "pseudo-events" during the drag-and-drop process, most importantly the OnData "event" which indicates that an object has been dropped on the associated window.

  • wxDataObject -- Provides storage and metadata relating to the data being transferred during a drag-and-drop operation. May support one of the built-in data types (text, bitmap, file), a single declared data type, or multiple data types. Includes: wxTextDataObject, wxBitmapDataObject, wxFileDataObject, wxDataObjectSimple, wxDataObjectComposite, wxDataObject

Process Overview

  • Create or choose a wxDataObject subclass appropriate to the data being shared

    • Provide OnData method to handle incoming data and update your application with the results of the drag-and-drop operation.

    • If you are not using a built-in data type, choose a type specifier (a unique string used to identify the datatype). Only targets whose type specifiers include one of the current data source specifiers will be eligible for drops.
  • Create a wxPyDropTarget subclass (and instance)

    • Provide an OnData method to handle a drop "event"

      • Call self.GetData() to transfer data to the target's wxDataObject instance

      • Call wxDataObject.GetData() to retrieve the actual shared data

      • Update your application to reflect drag-and-drop operation (in many cases you will need a pointer to the target window within the drop target instance to accomplish this).
    • Instantiate an instance of your wxDataObject class

    • Bind a wxDataObject to the drop target by calling SetDataObject. You will also want to keep a pointer to the wxDataObject in the drop target instance, so that you can call wxDataObject.GetData() within the OnData method.

    • Bind the drop target to the target window using wxWindow.SetDropTarget

  • Handle an event on the source window which signals the start of the drag-and-drop cycle
    • Create a wxDropSource

    • Set the data object of the drop source to another instance of your wxDataObject class

    • Call the drop source DoDragDrop() method to begin the drag-and-drop operation

    • Respond to the result code of the DoDragDrop method as appropriate to your application

wxDataObjects

  • Discuss the various concerns relating to the data object. Python pickling options Multiple formats -- currently only works for source in Python (as far as I can see) Format specifiers, do these need to be discussed? Special Data Types

Code Samples

  • Simple drag-and-drop

Toggle line numbers
   1 # A very simple Drag and Drop Example
   2 # provided with no warranty whatsoever for any purpose, ever
   3 
   4 # This code creates a Text Control from which Text can be dragged,
   5 # a Text Control to which Text can be dragged (from the first Text Control or from other applications),
   6 # and a Text Control to which Files can be dragged from outside this application.
   7 # While the later two windows can receive data from outside the application, the first window
   8 # does not appear to be able to provide text to other applications.  Please feel free to fix
   9 # this if you know how, as I think that would be more useful as an example.
  10 
  11 # It is designed to demonstrate the fundamentals of very simple drag-and-drop operations.
  12 
  13 """ This mini-ap is designed to demonstrate simple Drag and Drop functioning in wxPython """
  14 
  15 __author__ = 'David Woods, Wisconsin Center for Education Research <dwoods@wcer.wisc.edu>'
  16 
  17 # Import wxPython
  18 from wxPython.wx import *
  19 
  20 # Declare GUI Constants
  21 MENU_FILE_EXIT = 101
  22 DRAG_SOURCE    = 201
  23 
  24 # Define Text Drop Target class
  25 class TextDropTarget(wxTextDropTarget):
  26    """ This object implements Drop Target functionality for Text """
  27    def __init__(self, obj):
  28       """ Initialize the Drop Target, passing in the Object Reference to
  29           indicate what should receive the dropped text """
  30       # Initialize the wxTextDropTarget Object
  31       wxTextDropTarget.__init__(self)
  32       # Store the Object Reference for dropped text
  33       self.obj = obj
  34 
  35    def OnDropText(self, x, y, data):
  36       """ Implement Text Drop """
  37       # When text is dropped, write it into the object specified
  38       self.obj.WriteText(data + '\n\n')
  39 
  40 # Define File Drop Target class
  41 class FileDropTarget(wxFileDropTarget):
  42    """ This object implements Drop Target functionality for Files """
  43    def __init__(self, obj):
  44       """ Initialize the Drop Target, passing in the Object Reference to
  45           indicate what should receive the dropped files """
  46       # Initialize the wsFileDropTarget Object
  47       wxFileDropTarget.__init__(self)
  48       # Store the Object Reference for dropped files
  49       self.obj = obj
  50 
  51    def OnDropFiles(self, x, y, filenames):
  52       """ Implement File Drop """
  53       # For Demo purposes, this function appends a list of the files dropped at the end of the widget's text
  54       # Move Insertion Point to the end of the widget's text
  55       self.obj.SetInsertionPointEnd()
  56       # append a list of the file names dropped
  57       self.obj.WriteText("%d file(s) dropped at %d, %d:\n" % (len(filenames), x, y))
  58       for file in filenames:
  59          self.obj.WriteText(file + '\n')
  60       self.obj.WriteText('\n')
  61 
  62 
  63 
  64 class MainWindow(wxFrame):
  65    """ This window displays the GUI Widgets. """
  66    def __init__(self,parent,id,title):
  67        wxFrame.__init__(self,parent,-4, title, size = (800,600), style=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE)
  68        self.SetBackgroundColour(wxWHITE)
  69 
  70        # Menu Bar
  71        # Create a MenuBar
  72        menuBar = wxMenuBar()
  73        # Build a Menu Object to go into the Menu Bar
  74        menu1 = wxMenu()
  75        menu1.Append(MENU_FILE_EXIT, "E&xit", "Quit Application")
  76        # Place the Menu Item in the Menu Bar
  77        menuBar.Append(menu1, "&File")
  78        # Place the Menu Bar on the ap
  79        self.SetMenuBar(menuBar)
  80        #Define Events for the Menu Items
  81        EVT_MENU(self, MENU_FILE_EXIT, self.CloseWindow)
  82 
  83        # GUI Widgets
  84        # Define a Text Control from which Text can be dragged for dropping
  85        # Label the control
  86        wxStaticText(self, -1, "Text Drag Source  (left-click to select, right-click to drag)", (10, 1))
  87        # Create a Text Control
  88        self.text = wxTextCtrl(self, DRAG_SOURCE, "", pos=(10,15), size=(350,500), style = wxTE_MULTILINE|wxHSCROLL)
  89        # Make this control a Text Drop Target
  90        # Create a Text Drop Target object
  91        dt1 = TextDropTarget(self.text)
  92        # Link the Drop Target Object to the Text Control
  93        self.text.SetDropTarget(dt1)
  94        # Put some text in the control as a starting place to have something to copy
  95        for x in range(20):
  96           self.text.WriteText("This is line %d of some text to drag.\n" % x)
  97        # Define Right-Click as start of Drag
  98        EVT_RIGHT_DOWN(self.text, self.OnDragInit)
  99 
 100        # Define a Text Control to recieve Dropped Text
 101        # Label the control
 102        wxStaticText(self, -1, "Text Drop Target", (370, 1))
 103        # Create a read-only Text Control
 104        self.text2 = wxTextCtrl(self, -1, "", pos=(370,15), size=(410,235), style = wxTE_MULTILINE|wxHSCROLL|wxTE_READONLY)
 105        # Make this control a Text Drop Target
 106        # Create a Text Drop Target object
 107        dt2 = TextDropTarget(self.text2)
 108        # Link the Drop Target Object to the Text Control
 109        self.text2.SetDropTarget(dt2)
 110 
 111        # Define a Text Control to recieve Dropped Files
 112        # Label the control
 113        wxStaticText(self, -1, "File Drop Target (from off application only)", (370, 261))
 114        # Create a read-only Text Control
 115        self.text3 = wxTextCtrl(self, -1, "", pos=(370,275), size=(410,235), style = wxTE_MULTILINE|wxHSCROLL|wxTE_READONLY)
 116        # Make this control a File Drop Target
 117        # Create a File Drop Target object
 118        dt3 = FileDropTarget(self.text3)
 119        # Link the Drop Target Object to the Text Control
 120        self.text3.SetDropTarget(dt3)
 121 
 122        # Display the Window
 123        self.Show(true)
 124 
 125 
 126    def CloseWindow(self, event):
 127        """ Close the Window """
 128        self.Close()
 129 
 130    def OnDragInit(self, event):
 131        """ Begin a Drag Operation """
 132        # Create a Text Data Object, which holds the text that is to be dragged
 133        tdo = wxPyTextDataObject(self.text.GetStringSelection())
 134        # Create a Drop Source Object, which enables the Drag operation
 135        tds = wxDropSource(self.text)
 136        # Associate the Data to be dragged with the Drop Source Object
 137        tds.SetData(tdo)
 138        # Intiate the Drag Operation
 139        tds.DoDragDrop(True)
 140 
 141 
 142 
 143 class MyApp(wxApp):
 144    """ Define the Drag and Drop Example Application """
 145    def OnInit(self):
 146       """ Initialize the Application """
 147       # Declare the Main Application Window
 148       frame = MainWindow(None, -1, "Drag and Drop Example")
 149       # Show the Application as the top window
 150       self.SetTopWindow(frame)
 151       return true
 152       
 153 
 154 # Declare the Application and start the Main Loop
 155 app = MyApp(0)
 156 app.MainLoop()

- David K. Woods, Wisconsin Center for Education Research, University of Wisconsin, Madison

(If you like this example, there's another, more complex example of Drag and Drop behavior in the TreeControls section.)

  • File/bitmap/text

Comments...

I will add a example for dragging items in a wxTreeCtrl and what is more interresting how to drag a branch in a wxTreeCtrl. if added it will be found under ListAndTreeControls.

--René Freund


DragAndDrop (last edited 2012-06-05 19:58:29 by pool-71-175-100-238)

NOTE: To edit pages in this wiki you must be a member of the TrustedEditorsGroup.