PyGObject перетаскивание и изменение порядка виджетов

#python-3.x #drag-and-drop #gtk #gtk3 #pygobject

Вопрос:

Я пытаюсь реализовать DND в Gtk3 с помощью Python, но пока мне удалось поймать только drag-begin сигнал. Вот код:

 class MyWidget(Gtk.EventBox):
    def __init__(self):
        super(TrackBox, self).__init__()

        self.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, [], Gdk.DragAction.MOVE)
        self.connect('drag-begin', self._sig_drag_begin)
        self.connect('drag-data-get', self._sig_drag_data_get)

        self.drag_dest_set(Gtk.DestDefaults.HIGHLIGHT | Gtk.DestDefaults.DROP | Gtk.DestDefaults.MOTION, [Gtk.TargetEntry.new('GTK_MYWIDGET', Gtk.TargetFlags.SAME_APP, 0)], Gdk.DragAction.MOVE)
        self.connect('drag-drop', self._sig_drag_drop)
        self.connect('drag-data-received', self._sig_drag_data_received)

    def _sig_drag_begin(self, widget, context):
        print("drag begin")
        print(self, widget, context)

    def _sig_drag_data_get(self, widget, context, selection, info, timestamp):
        print("drag data get")
        print(self, widget, context, selection, info, timestamp)

    def _sig_drag_drop(self, widget, context, x, y, timestamp):
        print('drag-drop')
        print(self, widget, context, x, y, timestamp)

    def _sig_drag_data_received(self, widget, context, x, y, selection, info, timestamp):
        print('drag-data-received')
        print(self, widget, context, x, y, selection, info, timestamp)
 

Я получил результат _sig_drag_begin , но больше ничего. Цель состояла бы в том, чтобы иметь возможность переупорядочить эти Gtk.EventBox элементы внутри a Gtk.Box с несколько аналогичным конечным результатом, который мы можем получить с помощью переупорядочиваемого Gtk.TreeView .

Ответ №1:

Вот решение на случай, если у кого-то возникнет такой же вопрос:

 class TrackBox(Gtk.EventBox):
    def __init__(self, title, artist, id, year, length, album):
        super(TrackBox, self).__init__()
        
        # do your stuff here

        # Looks like this one is needed
        targs = [Gtk.TargetEntry.new("dummy", Gtk.TargetFlags.SAME_APP, 1)]

        self.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, targs, Gdk.DragAction.MOVE)

        self.drag_dest_set(Gtk.DestDefaults.HIGHLIGHT | Gtk.DestDefaults.DROP | Gtk.DestDefaults.MOTION, targs, Gdk.DragAction.MOVE)
        self.connect('drag-drop', self._sig_drag_drop)
        self.connect('drag-end', self._sig_drag_end)

    def _sig_drag_drop(self, widget, *_):
        # Here you get the name of the target
        print('drag-drop: get target name')
        print(widget.get_name())

    def _sig_drag_end(self, widget, _):
        # And here you get the name of the source
        # also you should write moving related code here
        print('drag-end: actually move and get source name')
        print(widget.get_name())
 

В этом видео все подробно объясняется.