以下代码显示一个带有按钮和树视图的窗口。 “clicked”信号的句柄附加到按钮并聚焦树视图。最初显示窗口时,树选择没有选定的项目,但是当树视图获得焦点时,将自动选择第一个项目。有没有办法在树视图获得焦点时保持选择?
点击前,按钮具有焦点,树选择没有选定项目。单击后,树视图具有焦点,但已选择一个项目。
由此产生的问题是我有一个接口通过附加树视图的树选择上的'已更改'信号来保持一些事物同步。显示窗口时,根据树视图在界面中的位置,默认情况下它们可能会获得焦点。这会导致“已更改”信号,并发生意外同步。可以为所有树视图调用 set_can_focus(False),但是:
同样地,我可以使用 grab_default 来确保在显示窗口时首先获得其他内容的焦点,但它不会使杂散焦点事件无法进行意外选择。
基于a posted answer表示选择模式SINGLE“需要至少选择一个项目”,并且这解释了为什么在焦点上选择了一个元素,我更多地考虑了选择模式常量。其中, SINGLE 和 BROWSE 似乎最相关。 pygtk文档GTK Selection Mode Constants仅表示:
gtk.SELECTION_SINGLE
点击即可进行单项选择gtk.SELECTION_BROWSE
通过指针浏览允许单个选择。
GTK + 3文档enum GtkSelectionMode详细介绍了一些内容:
GTK_SELECTION_SINGLE
可以选择零个或一个元素GTK_SELECTION_BROWSE
选择了一个元素。在一些 这种情况,例如最初或在搜索操作期间,它是 可能没有使用GTK_SELECTION_BROWSE选择任何元素。什么 真正强制的是用户无法取消选择当前 选择的元素除了选择另一个元素。
我在这里看不到任何暗示当选择模式为SINGLE时必须至少选择一个元素。
以下是重现窗口并作为示例的代码。
from gi.repository import Gtk
# A ListStore with some words
list_store = Gtk.ListStore(str)
for selection in "Can a machine think?".split():
list_store.append([selection])
# A TreeView with a single column
tree_view = Gtk.TreeView(model=list_store)
cell_renderer = Gtk.CellRendererText()
tree_view_column = Gtk.TreeViewColumn(cell_renderer=cell_renderer,text=0,title='Words')
tree_view.append_column(tree_view_column)
# A button to focus the list
focus = Gtk.Button(label='Focus List')
focus.connect('clicked',lambda *_: tree_view.grab_focus())
# A Box to hold everything, and a Window for the Box.
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
box.add(focus) # button on top gets initial focus
box.add(tree_view) # tree_view below doesn't, and has no selected items
window = Gtk.Window()
window.add(box)
window.show_all()
Gtk.main()
答案 0 :(得分:1)
查看root/gtk/gtktreeview.c for tree_view.grab_focus()中的源代码,我们可以看到gtk_tree_view_focus_to_cursor总是被调用,并选择第一个元素。在某些情况下,你可以解决这个问题。
这是一个讨厌的黑客。
它会覆盖grab_focus
方法,在调用grab_focus
之前存储选择,如果之前没有选择则清除选择。
def tree_view_grab_focus():
selection = tree_view.get_selection()
_, selected = selection.get_selected()
Gtk.TreeView.grab_focus(tree_view)
if selected is None:
selection.unselect_all()
tree_view.grab_focus = tree_view_grab_focus
不幸的是,它仅适用于从Python调用grab_focus
时,其他调用者(例如GTK的键盘导航)不适用。