Differences between revisions 13 and 14
Revision 13 as of 2008-03-11 10:50:28
Size: 10840
Editor: localhost
Comment: converted to 1.6 markup
Revision 14 as of 2008-06-15 12:37:57
Size: 10968
Editor: 82-69-91-89
Comment: Just updated the code in this example to the 'import wx' style
Deletions are marked like this. Additions are marked like this.
Line 100: Line 100:
# A very simple Drag and Drop Example
# provided with no warranty whatsoever for any purpose, ever
Line 109: Line 112:
""" This mini-ap is designed to demonstrate simple Drag and Drop functioning in wxPython """ """ This mini-ap is designed to demonstrate simple Drag and Drop functioning in wx.Python """
Line 113: Line 116:
# Import wxPython
from wxPython.wx import *
# Import wx.Python
import wx
Line 117: Line 120:
MENU_FILE_EXIT = 101
DRAG_SOURCE = 201
MENU_FILE_EXIT = wx.NewId()
DRAG_SOURCE = wx.NewId()
Line 121: Line 124:
class TextDropTarget(wxTextDropTarget): class TextDropTarget(wx.TextDropTarget):
Line 126: Line 129:
      # Initialize the wxTextDropTarget Object
      wxTextDropTarget.__init__(self)
      # Initialize the wx.TextDropTarget Object
      wx.TextDropTarget.__init__(self)
Line 137: Line 140:
class FileDropTarget(wxFileDropTarget): class FileDropTarget(wx.FileDropTarget):
Line 143: Line 146:
      wxFileDropTarget.__init__(self)       wx.FileDropTarget.__init__(self)
Line 160: Line 163:
class MainWindow(wxFrame): class MainWindow(wx.Frame):
Line 163: Line 166:
       wxFrame.__init__(self,parent,-4, title, size = (800,600), style=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE)
       self.SetBackgroundColour(wxWHITE)
       wx.Frame.__init__(self,parent,-4, title, size = (800,600), style=wx.DEFAULT_FRAME_STYLE|wx.NO_FULL_REPAINT_ON_RESIZE)
       self.SetBackgroundColour(wx.WHITE)
Line 168: Line 171:
       menuBar = wxMenuBar()        menuBar = wx.MenuBar()
Line 170: Line 173:
       menu1 = wxMenu()        menu1 = wx.Menu()
Line 177: Line 180:
       EVT_MENU(self, MENU_FILE_EXIT, self.CloseWindow)        wx.EVT_MENU(self, MENU_FILE_EXIT, self.CloseWindow)
Line 182: Line 185:
       wxStaticText(self, -1, "Text Drag Source (left-click to select, right-click to drag)", (10, 1))        wx.StaticText(self, -1, "Text Drag Source (left-click to select, right-click to drag)", (10, 1))
Line 184: Line 187:
       self.text = wxTextCtrl(self, DRAG_SOURCE, "", pos=(10,15), size=(350,500), style = wxTE_MULTILINE|wxHSCROLL)        self.text = wx.TextCtrl(self, DRAG_SOURCE, "", pos=(10,15), size=(350,500), style = wx.TE_MULTILINE|wx.HSCROLL)
Line 194: Line 197:
       EVT_RIGHT_DOWN(self.text, self.OnDragInit)        wx.EVT_RIGHT_DOWN(self.text, self.OnDragInit)
Line 198: Line 201:
       wxStaticText(self, -1, "Text Drop Target", (370, 1))        wx.StaticText(self, -1, "Text Drop Target", (370, 1))
Line 200: Line 203:
       self.text2 = wxTextCtrl(self, -1, "", pos=(370,15), size=(410,235), style = wxTE_MULTILINE|wxHSCROLL|wxTE_READONLY)        self.text2 = wx.TextCtrl(self, -1, "", pos=(370,15), size=(410,235), style = wx.TE_MULTILINE|wx.HSCROLL|wx.TE_READONLY)
Line 209: Line 212:
       wxStaticText(self, -1, "File Drop Target (from off application only)", (370, 261))        wx.StaticText(self, -1, "File Drop Target (from off application only)", (370, 261))
Line 211: Line 214:
       self.text3 = wxTextCtrl(self, -1, "", pos=(370,275), size=(410,235), style = wxTE_MULTILINE|wxHSCROLL|wxTE_READONLY)        self.text3 = wx.TextCtrl(self, -1, "", pos=(370,275), size=(410,235), style = wx.TE_MULTILINE|wx.HSCROLL|wx.TE_READONLY)
Line 219: Line 222:
       self.Show(true)        self.Show(True)
Line 229: Line 232:
       tdo = wxPyTextDataObject(self.text.GetStringSelection())        tdo = wx.PyTextDataObject(self.text.GetStringSelection())
Line 231: Line 234:
       tds = wxDropSource(self.text)        tds = wx.DropSource(self.text)
Line 239: Line 242:
class MyApp(wxApp): class MyApp(wx.App):
Line 247: Line 250:
      return true
      
      return True
Line 269: Line 272:

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