简体   繁体   中英

How do I implement a drag and drop system in a Gtk TreeView?

I am teaching myself Python Gtk+3 using the readthedocs tutorial. I'm currently working on drag and drop and want to create a TreeView where every line is dragable. To do this, my code reads in a list of telecommands and puts them in a TreeView. This TreeView works and I can drag the single lines around. When I drop them into the designated drop area however, nothing happens.

My current goal is for the program to just print the text "Received data", whenever I drop something. Later on, I want the program to print out the single commands, that have been dropped.

My code looks as follows(I followed this example):

import gi

gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk

from csv import reader

# get data from file and format it
with open ("TC_list.csv", "r") as read_command_list:
    csv_reader = reader(read_command_list)
    list_of_commands = list(csv_reader)
    list_header = list_of_commands.pop(0)

for command in list_of_commands:
    command[0] = int(command[0])
    command[1] = int(command[1])

DRAG_ACTION  = Gdk.DragAction.COPY


class DragDropWindow(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self, title="Drag and Drop Demo")

        self.grid = Gtk.Grid()
        self.grid.set_column_homogeneous(True)
        self.grid.set_row_homogeneous(True)
        self.add(self.grid)
        self.grid.set_size_request(1200, 1000)

        self.listview = DragSourceListView()
        self.drop_area = DropArea()

        self.grid.attach(self.listview, 0, 0, 1, 1)
        self.grid.attach_next_to(self.drop_area, self.listview, \
            Gtk.PositionType.BOTTOM, 1, 1)


class DragSourceListView(Gtk.Grid):
    def __init__(self):
        Gtk.Grid.__init__(self)

        # Creating ListStore model
        self.telecommand_liststore = Gtk.ListStore(int, int, str, str)
        for telecommand_ref in list_of_commands:
            self.telecommand_liststore.append(list(telecommand_ref))
        self.current_filter_telecommand = None

        # Creating the filter, feeding it with the liststore model
        self.telecommand_filter = self.telecommand_liststore.filter_new()
        # setting the filter function
        self.telecommand_filter.set_visible_func(self.telecommand_filter_func)

        # creating the treeview, making it use the filter a model, adding columns
        self.treeview = Gtk.TreeView.new_with_model(Gtk.TreeModelSort(self.telecommand_filter))
        for i, column_title in enumerate(list_header):
            renderer = Gtk.CellRendererText()
            column = Gtk.TreeViewColumn(column_title, renderer, text=i)
            column.set_sort_column_id(i)
            self.treeview.append_column(column)

        # set up drag-source
        self.treeview.enable_model_drag_source(Gdk.ModifierType.BUTTON1_MASK, [], DRAG_ACTION)
        self.treeview.connect("drag-data-get", self.on_drag_data_get)

        # setting up layout, treeview in scrollwindow
        self.scrollable_treelist = Gtk.ScrolledWindow()
        self.scrollable_treelist.set_vexpand(True)
        self.scrollable_treelist.set_hexpand(True)
        self.attach(self.scrollable_treelist, 0, 1, 8, 10)

        self.scrollable_treelist.add(self.treeview)


    def telecommand_filter_func(self, model, iter, data):
        if (
            self.current_filter_telecommand is None
            or self.current_filter_telecommand == "None"
        ):
            return True
        else:
            return model[iter][0] == self.current_filter_telecommand


    def on_drag_data_get(self, widget, drag_context, dat, info, time):
        selected_tc = self.get_selected_items()[0]
        selected_iter = self.get_model().get_iter(selected_tc)



class DropArea(Gtk.Label):
    def __init__(self):
        Gtk.Label.__init__(self)
        self.set_label("Drop Area")
        self.drag_dest_set(Gtk.DestDefaults.ALL, [], DRAG_ACTION)

        self.connect("drag-data-received", self.on_drag_data_received)

    def on_drag_data_received(self, widget, drag_context, x, y, data, info, time):
        print("Received data")



win = DragDropWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()

What am I overlooking here? Why doesn't the drop-area do anything?

Try to set gtk_tree_view_set_reorderable to True .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM