我有一个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
个对象才能工作。
我错过了其他人完全明显的东西吗?
答案 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.TreePath
和Gtk.TreeIter
个对象的引用,由变量Gtk.TreeModelRow.path
和Gtk.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()