在没有 UI 的情况下更改选择后,TreeView 多项选择无法正常工作
TreeView multiple selection does not work correctly after changing selection without UI
这可能是一个错误,尽管我可能误解了什么。
简要说明
基本上,我发现使用 "Shift+Arrows" 在 Gtk.TreeView
中执行多个 selection 在使用 [=13] 更改 selection 后无法正常工作=].另一方面,如果您通过单击行然后按 "Shift+Arrows" 来更改 selection,则 selection 的行为与预期的一样。
我应该注意,如果您通过调用 Gtk.TreeSelection.select_iter
更改 selected 行,UI 会按预期更新并调用 Gtk.TreeSelection.get_selected_rows()
returns 它应该的行。只有当您尝试使用箭头键 select 多行时才会出现奇怪的行为。
这可能在这个自包含的例子中得到了最好的说明,我试图使它尽可能简单:
代码
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
class TreeViewBug(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self)
self.connect('destroy', Gtk.main_quit)
# Create model consisting of row path and a name
self.treeModel = Gtk.ListStore(int, str)
self.treeModel.append([0, 'alice'])
self.treeModel.append([1, 'bob'])
self.treeModel.append([2, 'chad'])
self.treeModel.append([3, 'dan'])
self.treeModel.append([4, 'emma'])
self.treeView = Gtk.TreeView()
self.treeView.append_column(Gtk.TreeViewColumn('path', Gtk.CellRendererText(), text=0))
self.treeView.append_column(Gtk.TreeViewColumn('name', Gtk.CellRendererText(), text=1))
self.treeView.set_model(self.treeModel)
# Allow for multiple selection
self.treeView.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
self.add(self.treeView)
def run(self):
self.show_all()
# Focus the TreeView so we can test multiple select via keyboard without clicking on a row
self.treeView.grab_focus()
# Manually change the selected row to the row with "chad"
chadIter = self.treeModel[2].iter
self.treeView.get_selection().select_iter(chadIter)
print('Press "Shift+Down" and see what happens')
print(' it should select "chad, dan", but instead it selects "bob, chad"')
print('Afterwards, try clicking on "chad" and then pressing Shift+Down. It should behave normally')
Gtk.main()
if __name__ == '__main__':
tv = TreeViewBug()
tv.run()
我尝试过的事情
我最初遇到这个错误是因为我的代码通过 Gtk.TreeSelection.select_iter
更改了 selected 行以响应按钮单击。
我也试过:
- 添加自定义 select 函数(
Gtk.TreeSelection.set_select_function
)
- 在更改之前清除 selection (
Gtk.TreeSelection.unselect_all
)
- 异步更改 selection (
GLib.idle_add
)。
- 改变selection
后重绘TreeView
猜测
我猜 TreeView
/TreeViewSelection
有一些内部状态变量跟踪 select离子和行,出于某种原因,当 TreeSelection.select_iter
被调用。这些变量可能与 UI 功能有关,因为 TreeSelection.get_selected_rows
仍然可以正常工作。 UI 需要额外的状态信息也是有道理的,因为多个 selection 的 UI 逻辑取决于之前的 UI 交互(Shift+Down 在扩展 select离子取决于你最初是select向上还是向下)
因为Gtk.TreeView使用了MVC,所以实际上需要设置treeview的cursor。这可能会影响程序的其余部分,具体取决于您在做什么。示例:
#chadIter = self.treeModel[2].iter
#self.treeView.get_selection().select_iter(chadIter)
path = 2
column = self.treeView.get_column(0)
edit = False
self.treeView.set_cursor(path, column, edit)
这可能是一个错误,尽管我可能误解了什么。
简要说明
基本上,我发现使用 "Shift+Arrows" 在 Gtk.TreeView
中执行多个 selection 在使用 [=13] 更改 selection 后无法正常工作=].另一方面,如果您通过单击行然后按 "Shift+Arrows" 来更改 selection,则 selection 的行为与预期的一样。
我应该注意,如果您通过调用 Gtk.TreeSelection.select_iter
更改 selected 行,UI 会按预期更新并调用 Gtk.TreeSelection.get_selected_rows()
returns 它应该的行。只有当您尝试使用箭头键 select 多行时才会出现奇怪的行为。
这可能在这个自包含的例子中得到了最好的说明,我试图使它尽可能简单:
代码
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
class TreeViewBug(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self)
self.connect('destroy', Gtk.main_quit)
# Create model consisting of row path and a name
self.treeModel = Gtk.ListStore(int, str)
self.treeModel.append([0, 'alice'])
self.treeModel.append([1, 'bob'])
self.treeModel.append([2, 'chad'])
self.treeModel.append([3, 'dan'])
self.treeModel.append([4, 'emma'])
self.treeView = Gtk.TreeView()
self.treeView.append_column(Gtk.TreeViewColumn('path', Gtk.CellRendererText(), text=0))
self.treeView.append_column(Gtk.TreeViewColumn('name', Gtk.CellRendererText(), text=1))
self.treeView.set_model(self.treeModel)
# Allow for multiple selection
self.treeView.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
self.add(self.treeView)
def run(self):
self.show_all()
# Focus the TreeView so we can test multiple select via keyboard without clicking on a row
self.treeView.grab_focus()
# Manually change the selected row to the row with "chad"
chadIter = self.treeModel[2].iter
self.treeView.get_selection().select_iter(chadIter)
print('Press "Shift+Down" and see what happens')
print(' it should select "chad, dan", but instead it selects "bob, chad"')
print('Afterwards, try clicking on "chad" and then pressing Shift+Down. It should behave normally')
Gtk.main()
if __name__ == '__main__':
tv = TreeViewBug()
tv.run()
我尝试过的事情
我最初遇到这个错误是因为我的代码通过 Gtk.TreeSelection.select_iter
更改了 selected 行以响应按钮单击。
我也试过:
- 添加自定义 select 函数(
Gtk.TreeSelection.set_select_function
) - 在更改之前清除 selection (
Gtk.TreeSelection.unselect_all
) - 异步更改 selection (
GLib.idle_add
)。 - 改变selection 后重绘
TreeView
猜测
我猜 TreeView
/TreeViewSelection
有一些内部状态变量跟踪 select离子和行,出于某种原因,当 TreeSelection.select_iter
被调用。这些变量可能与 UI 功能有关,因为 TreeSelection.get_selected_rows
仍然可以正常工作。 UI 需要额外的状态信息也是有道理的,因为多个 selection 的 UI 逻辑取决于之前的 UI 交互(Shift+Down 在扩展 select离子取决于你最初是select向上还是向下)
因为Gtk.TreeView使用了MVC,所以实际上需要设置treeview的cursor。这可能会影响程序的其余部分,具体取决于您在做什么。示例:
#chadIter = self.treeModel[2].iter
#self.treeView.get_selection().select_iter(chadIter)
path = 2
column = self.treeView.get_column(0)
edit = False
self.treeView.set_cursor(path, column, edit)