I have a Gtk.TreeView
here. Most but not all of the items should be able to be dragged & dropped. In this example the first item should not be able to be dragged & dropped but it should be selectable.
How can I realize this? Maybe I have to use the drag-begin
signal and stop the drag in there. But I don't know how.
#!/usr/bin/env python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import Gdk
class MainWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="TreeView Drag and Drop")
self.connect("delete-event", Gtk.main_quit)
self.set_default_size(400, 300)
# "model" with dummy data
self.store = Gtk.TreeStore(str)
self.store.append(None, ['do not drag this'])
self.store.append(None, ['drag this'])
self.view = Gtk.TreeView(model=self.store)
self.add(self.view)
# build columsn
colA = Gtk.TreeViewColumn('Col A', Gtk.CellRendererText(), text=0)
self.view.append_column(colA)
# DnD events
self.view.connect("drag-data-received", self.drag_data_received)
self.view.connect("drag-data-get", self.drag_data_get)
self.view.connect("drag-begin", self.drag_begin)
target_entry = Gtk.TargetEntry.new('text/plain', 2, 0)
self.view.enable_model_drag_source(
Gdk.ModifierType.BUTTON1_MASK,[target_entry],
Gdk.DragAction.DEFAULT|Gdk.DragAction.MOVE
)
self.view.enable_model_drag_dest(
[target_entry],
Gdk.DragAction.DEFAULT|Gdk.DragAction.MOVE
)
def drag_data_get (self, treeview, drag_context, data, info, time):
model, path = treeview.get_selection().get_selected_rows()
print('dd-get\tpath: {}'.format(path))
data.set_text(str(path[0]), -1)
def drag_data_received (self, treeview, drag_context, x,y, data,info, time):
print('dd-received')
store = treeview.get_model()
source_iter = store.get_iter(data.get_text())
dest_path, drop_pos = self.view.get_dest_row_at_pos(x, y)
print('path: {} pos: {}'.format(dest_path, drop_pos))
def drag_begin(self, widget, context):
print(widget)
print(context)
win = MainWindow()
win.show_all()
Gtk.main()
The correct way of canceling a drag and drop operation is to click the right mouse button once you have started to drag the files and folders around. Windows will automatically cancel the operation so that everything is returned to its initial state.
To hide the not-allowed cursor and make your drop zones valid you need to apply preventDefault on both dragOver and dragEnter.
HTML drag-and-drop uses the DOM event model and drag events inherited from mouse events . A typical drag operation begins when a user selects a draggable element, drags the element to a droppable element, and then releases the dragged element.
The Dragging state is used whenever the user is dragging a drag object. The Returning state is used whenever a drag object has been dropped in the wrong place and returns to its original position if not dropped in a drop zone. The Dropped state is used whenever a drag object is dropped into a drop zone.
You have to overload Gtk.TreeDragSource.do_row_draggable()
.
class MyTreeStore (Gtk.TreeStore):
# ...
def do_row_draggable(self, path):
# do your decision here
return True # draggable
return False # NOT draggable
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With