1

I have a simple gtk.TreeView with a gtk.ListStore model and set_reorderable(True), I want to catch the signal/event emited when the user reorder through drag&drop the list, but the documentation does not help much:

"The application can listen to these changes by connecting to the model's signals"

So I tried to connect the model (ListStore) signals... but surprise! ListStore has no signals, so you are dispatched to TreeModel signals, then I tried to connect with the TreeModel "rows-reordered" signal with no lucky.

How should I catch the list reorder performed by the user?

gpoo
  • 8,408
  • 3
  • 38
  • 53
Htechno
  • 5,901
  • 4
  • 27
  • 37
  • 1
    Note that the Gtk docs state "this signal is _not_ emitted when rows are reordered by DND, since this is implemented by removing and then reinserting the row." – alldayremix Sep 29 '13 at 18:35

2 Answers2

3

There is no way to do that in PyGTK currently. "rows-reordered" is the correct signal, but it is impossible to derive any information from it in PyGTK other than "somehow reordered". In C GTK+ you could use the same signal and get the required information in callback, but not in Python.

  • But this signal is not emited in PyGTK, at least I could check manually the model if was emited. – Htechno May 14 '10 at 22:20
  • 2
    @mkotechno: What exactly are you doing? If you drag'n'drop rows, "rows-reordered" is *not* sent, even if it looks like reordering from GUI. Instead, during drag'n'drop "row-deleted" and "row-inserted" signals are emitted. –  May 15 '10 at 18:13
  • 1
    @doublep Please add this to the answer. And it might be worth mentioning that `row-deleted` is the better choice because at the point of `row-inserted` there is one dummy row from the drag and drop operation in the model. – schlamar Aug 29 '13 at 11:38
0

I too had this problem and the docs are unclear. But here's what I found

'rows-reordered' signal is emitted when you have

tvcolumn.set_sort_column_id(0)

However you still bind the signal to the treemodel.

treestore = gtk.TreeStore(str, object)
treestore.connect("rows-reordered", self.rows_r)

That will cause the visible column header to become clickable. When you click on the column header, it will reorder the items in the tree in ascending order and then in descending order if you click it again, and back and forth.

Here's a simple code you can test and see what i mean.

import pygtk
pygtk.require('2.0')
import gtk

class BasicTreeViewExample:

    def __init__(self):
        window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        window.set_title("Treeview")
        window.set_size_request(200, 200)
        window.connect("destroy", lambda w: gtk.main_quit())

        treestore = gtk.TreeStore(str)
        treestore.connect("rows-reordered", self.rows_reordered)

        for i in range(4):
            piter = treestore.append(None, ['Item %i' % i])

        treeview = gtk.TreeView(treestore)

        tvcolumn = gtk.TreeViewColumn('Click Me!')

        treeview.append_column(tvcolumn)

        cell = gtk.CellRendererText()

        tvcolumn.pack_start(cell, True)

        tvcolumn.add_attribute(cell, 'text', 0)

        # This allows the column header ("Click me!") to be clickable and sort/order items
        tvcolumn.set_sort_column_id(0)

        window.add(treeview)
        window.show_all()


    def rows_reordered(self, a, b, c, d):
        print a
        print b
        print c
        print d


def main():
    gtk.main()

if __name__ == "__main__":
    tvexample = BasicTreeViewExample()
    main()
sqram
  • 7,069
  • 8
  • 48
  • 66