Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cancel a Drag & Drop for some specific items in a Gtk.TreeView

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()
like image 506
buhtz Avatar asked Aug 22 '18 20:08

buhtz


People also ask

How do I cancel drag?

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.

How do I disable not allowed cursor when dragging?

To hide the not-allowed cursor and make your drop zones valid you need to apply preventDefault on both dragOver and dragEnter.

What happens when user drops a dragged object?

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.

What is dragging state?

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.


1 Answers

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
like image 140
buhtz Avatar answered Oct 05 '22 23:10

buhtz