Это потенциально ошибка, хотя, возможно, я что-то неправильно понимаю.

Краткое описание

По сути, я обнаружил, что использование «Shift + стрелки» для выполнения множественного выделения в Gtk.TreeView не работает правильно после изменения выделения с помощью Gtk.TreeSelection.select_iter. С другой стороны, если вы измените выделение, щелкнув строку, а затем нажав «Shift + стрелки», выделение будет вести себя так, как и следовало ожидать.

Я должен отметить, что если вы измените выбранную строку, вызвав Gtk.TreeSelection.select_iter, пользовательский интерфейс обновится, как и следовало ожидать, а вызов Gtk.TreeSelection.get_selected_rows() вернет те строки, которые должны. Странное поведение возникает только тогда, когда вы пытаетесь выбрать несколько строк с помощью клавиш со стрелками.

Возможно, лучше всего это проиллюстрировано в этом автономном примере, который я попытался сделать как можно проще:

Код

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 в ответ на нажатие кнопки.

Я также пробовал:

  • добавление пользовательской функции выбора (Gtk.TreeSelection.set_select_function)
  • очистка выбора перед его изменением (Gtk.TreeSelection.unselect_all)
  • асинхронное изменение выделения (GLib.idle_add).
  • перерисовка TreeView после изменения выделения

Предположения

Я предполагаю, что TreeView / TreeViewSelection имеет некоторый выбор для отслеживания внутренней переменной состояния и строку, которая по какой-то причине не обновляется должным образом при вызове TreeSelection.select_iter. Эти переменные, вероятно, связаны с функциями пользовательского интерфейса, потому что TreeSelection.get_selected_rows по-прежнему работает правильно. Также имеет смысл, что пользовательскому интерфейсу потребуется дополнительная информация о состоянии, поскольку логика пользовательского интерфейса множественного выбора зависит от предыдущего взаимодействия с пользовательским интерфейсом (Shift + Down ведет себя по-разному при расширении выбора в зависимости от того, изначально вы выбрали вверх или вниз)

2
sicklybeans 18 Окт 2019 в 20:34

1 ответ

Лучший ответ

Поскольку Gtk.TreeView использует MVC, вам действительно нужно установить курсор древовидной структуры. Это может повлиять на остальную часть программы, в зависимости от того, что вы делаете. Пример:

#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)
1
theGtknerd 19 Окт 2019 в 02:08