The various event functions of your wx.DropTarget subclass get called when a drop occurs. The most important of these is OnData(x, y, default), which is the one event method that you must override in your custom drop target class. The x and y parameters are the location of the cursor at the time of the drop. The default parameter is the default result of the drop operation (i.e., copy or move), and is one of the four values listed earlier as possible return values for DoDrag-Drop(). Exactly which value gets passed as the default is based on the underlying operating system, the flags passed to DoDragDrop(), and the state of the modifier keyboard keys when the drop occurs. In practice, this usually means that if no keyboard keys are pressed, you get the default as specified by DoDragDrop(), but if the control or command key is pressed, you get the other operation if both are allowed by the call to DoDragDrop(). Within the OnData() method (and only within the OnData() method), you can call GetData(). The GetData() method takes the actual data from the drop source and puts it in the data object associated with your drop target object. Contrary to your probable expectation, GetData() does not return the data object, which is one reason why you would usually hold onto your data object as an instance variable. Here is the boilerplate code for MyDropTarget.OnData().
def OnData(self, x, y, default): self.GetData()
actual_data = self.data.GetText() # Do something with the data here... return default
The return value of OnData() should be the resulting operation—you should return the default value, unless there is an error and you need to return wx.Drag-None. Once you have the data, you can do whatever you want with it. Remember, since OnData() returns information about the resulting operation, rather than the data itself, if you want to use the data elsewhere, you need to put it in an instance variable where it will still be accessible outside the method.
After the drop operation is either completed or canceled, the result value returned from OnData() is returned from DoDragDrop(), and the drop source's thread continues forward.
Within the wx.DropTarget class there are five On... methods that you can override in your subclass to provide custom behavior when the target invoked. We've already seen OnData(). Here are the others.
OnDrop(x, y), OnEnter(x, y, default) , OnDragOver(x, y, default), and OnLeave().
The meanings of the x, y, and default parameters are all as in OnData(). You do not need to override any of these methods, but you can if you want to provide custom feedback or functionality in your application.
The OnEnter() method is called first, when the mouse enters the drop target. You might use this to update a status window, for example. It returns the operation to be performed if a drop occurs (usually the one specified by the default parameter) or wx.DragNone if you will not accept the drop. The return value of this method is used by wxPython to specify which icon or cursor is used as the mouse glides over the window. The method OnDragOver() is called continuously as the mouse is inside the window, and again, it returns the desired operation or wx.DragNone. The method OnDrop() is called when the mouse is released and the drop occurs, and it calls OnData() by default. Finally, OnLeave() is called as the cursor exits the window in question.
As with data objects, wxPython provides a couple of predefined drop target classes to cover the most common cases. You still need to create a subclass and override a method to handle the data, but in this case the predefined class handles the wx.DataObject for you. For text, the class wx.TextDropTarget provides the overridable method OnDropText(x, y, data). You would override this method instead of OnData(). The x and y are the drop coordinates, and the data parameter is the string being dropped, which you can use immediately without having to make further queries about data objects. Your override should return True if you accept the new text, and False otherwise. For file drops, the predefined class is wx.FileDropTarget, and the method to override is OnDropFiles(x, y, filenames), where filenames is a list of the names of the files being dropped. Again, you can manipulate them as needed, and return True or False when done.
Was this article helpful?