如何向上或向下移动多个ListStore元素

时间:2014-06-15 08:59:55

标签: listview python-3.x gtk3

我有一个Gtk.ListStore模型,其中包含标题和作者信息,我希望用户能够移动元素以按照他们选择的任何顺序放置它们。这意味着提供" Move Up"并且"向下移动"的按钮。

不幸的是,我在this question中找到的逻辑与Gtk.TreeView合作,不允许选择多个元素。

Gtk.TreeSelection.get_selected()返回一个包含Gtk.TreeIter的元组,该元组指向当前选中的单个行,但Gtk.TreeSelection.get_selected_rows()返回包含Gtk.TreePath个元素列表的元组

与上面链接的单选行问题的答案仅适用于Gtk.TreeIter个对象,而且我还无法弄清楚如何将Gtk.TreePath转换为Gtk.TreeIter对象。

然而,我确实找到了Gtk.ListStore.move_above(iter, position)Gtk.ListStore.move_below(iter, position)方法,但同样,它们需要Gtk.TreeIter个对象才能工作。

我错过了其他人完全明显的东西吗?

3 个答案:

答案 0 :(得分:2)

Gtk.ListStore.move_above(iter, position)Gtk.ListStore.move_below(iter, position)是正确的调用方法,然而,事实证明,我正在阅读的文档相对于我使用的Python 3和Gtk3接口的版本实际上是错误的。
(道歉,我不知道如何弄清楚我正在使用的接口版本)

Gtk.TreeSelection.get_selected_rows()实际上返回一个包含Gtk.TreeModelRow的元组和我正在使用的模型的表示。

Gtk.TreeModelRow包含对给定行的相应Gtk.TreePathGtk.TreeIter个对象的引用,由变量Gtk.TreeModelRow.pathGtk.TreeModelRow.iter引用。

所以,我的最终代码是移动多个选定的行:

selection = treeView.get_selection()
selections, model = selection.get_selected_rows()

for row in selections:
    # Make sure the row we are given is actually selected
    if selection.iter_is_selected(row.iter) and row.previous != None:
        self.listData.move_before(row.iter, row.previous.iter)

我的代码用于移动多个选定的行:

selection = treeView.get_selection()
selections, model = selection.get_selected_rows()

# Note: Must loop through rows in the opposite direction so as not to move a row all the way to the bottom
for i in range(len(selections)-1, -1, -1):
    row = selections[i]
    # Make sure the row we are given is actually selected
    if selection.iter_is_selected(row.iter) and row.next != None:
        self.listData.move_after(row.iter, row.next.iter)

答案 1 :(得分:1)

此问题的已接受答案使用row.previous,我在我的版本中似乎没有。这是我移动行的解决方案。它似乎工作正常,但我很容易接受建议和批评,因为我是Python和PyGtk的新手,目前正在使用Python 2.7和PyGtk2

@staticmethod
    def _move_item_up(list_store, list_widget):
        selection = list_widget.get_selection()
        selections, model = selection.get_selected_rows()
        for row in selections:
            previous_path = (row.path[0]-1,)
            if selection.iter_is_selected(row.iter) and previous_path[0] > -1:
                list_store.move_before(row.iter, list_store.get_iter(previous_path))

答案 2 :(得分:0)

接受的答案使用所有库中不存在的未记录成员。当你试图向上移动已经在顶部的行时,另一个有一个错误:它会将顶部的一个循环到选择的底部,将所有其他选定的行向上移动一个。

这是一个适用于上下的工作解决方案。

def move_selected_items_up(treeView):
    selection = treeView.get_selection()
    model, selected_paths = selection.get_selected_rows()
    for path in selected_paths:
        index_above = path[0]-1
        if index_above < 0:
            return
        model.move_before(model.get_iter(path), model.get_iter((index_above,)))

def move_selected_items_down(treeView):
    selection = treeView.get_selection()
    model, selected_paths = selection.get_selected_rows()
    for path in reversed(selected_paths):
        index_below = path[0]+1
        if index_below >= len(model):
            return
        model.move_after(model.get_iter(path), model.get_iter((index_below,)))

以@ codedog的回答为出发点。最初修改只是为了修复错误,但通过更好地使用从get_selected_rows()

返回的值进行简化