Reputation: 181
I want to use drag&drop in combination with wx.dataview.DataViewCtrl
, so I started with trying to reorder rows using Drag&Drop. I was unable to find any examples how to do this correctly in wxpython, but anyhow, I managed to get it partially working (see below).
Unfortunately, event.GetDataObject()
always returns None
in my on_drop
function. Any pointers how to get the DataObject I assigned in on_begin_drag
? What am I doing wrong?
Thanks in advance!
Setup:
Example Code:
import wx
import wx.dataview
DF_PLAYLIST_SONG = wx.CustomDataFormat("playlist_song")
class MyDataViewCtrl(wx.dataview.DataViewCtrl)
def __init__(self, *args. **kwargs)
[...]
self.Bind(wx.dataview.EVT_DATAVIEW_ITEM_BEGIN_DRAG, self.on_begin_drag)
self.Bind(wx.dataview.EVT_DATAVIEW_ITEM_DROP, self.on_drop)
self.EnableDragSource(DF_PLAYLIST_SONG)
self.EnableDropTarget(DF_PLAYLIST_SONG)
[...]
def on_begin_drag(self, event):
text = self._model.GetValue(event.GetItem(), 0)
data = wx.CustomDataObject(DF_PLAYLIST_SONG)
# Need to encode, because SetData dislikes unicode
data.SetData(text.encode('utf-8'))
event.SetDataObject(data)
#data.this.disown() # Makes no difference if uncommented or not
def on_drop(self, event):
print(event.GetDataFormat()) # Returns DF_PLAYLIST_SONG
if event.GetDataFormat() == DF_PLAYLIST_SONG:
# This would be logical choice:
print(event.GetDataSize()) # Returns the size of the data, e.g 92
print(event.GetDataObject()) # Returns None (strange!)
# Some other stuff I tried
print(event.GetClientObject()) # Returns MyDataViewCtrl instance
print(event.GetEventObject()) # Returns None
print(event.GetValue()) # Returns <Swig Object of type 'wxVariant *' at 0x7fffa340a0d0>
print(self._model.GetValue(event.GetItem(), 0)) # Returns column 0 of the row this was dropped on
print(event.GetItem()) # Returns the wx.dataview.DataViewItem this was dropped on
print(event.GetDataBuffer()) # Returns <Swig Object of type 'void *' at 0x1a59b30>
Upvotes: 0
Views: 2097
Reputation: 3177
See this example on a wxWidgets/wxPython ticket 15100. I used it to make drag/drop for a wx.DataViewCtrl
and a tree-ish data structure happen (to get an object back). Works at least on 2.9.5/msw. HitTest
has been implemented in 3.0.2 (if you want to know which item got hit).
May not be the proper answer for your problem but at least it does work (see the crazy pickling of the object item).
Upvotes: 0
Reputation: 22708
You don't get back the data object in wxEVT_DATAVIEW_ITEM_DROP
hander, it's only used for dragging data away from the control. When dropping, you get the raw data and its format, i.e. you should use GetDataSize()
and GetDataBuffer()
to access it.
Upvotes: 1