PyGtk Как изменить данные TreeView с помощью фильтра?

То, что я пытаюсь сделать, это динамически изменять (через фильтр) список строк. В моем случае это список файлов с путями, хранящимися в gtk.TreeStore .

Пример ожидаемого эффекта (например, поиск файла Sublime Text 2 Ctrl + P ):

Данные:

Список файлов (treeview):

  • '/home/user/'
    • '.bashrc',
    • 'test.txt',
  • ...

Действие: В поле фильтра (виджет ввода) пользователь начинает печатать. После первого символа, например. Список 't' должен обновляться следующим образом:

Результат:

Список файлов (treeview):

  • 'test.txt',
  • ... все строки, содержащие 't' (теперь функция сопоставления не важна)

Что у меня уже есть:

self.search_entry = gtk.Entry()

self.tree_store = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_BOOLEAN)

for node, files in self.files_list:
    parent = self.tree_store.append(None, [node, True])
    for f in files:
        self.tree_store.append(parent, [f, True])

tree_filter = self.tree_store.filter_new()
self.treeview = gtk.TreeView(tree_filter)

self.renderer0 = gtk.CellRendererText()
self.treeview.insert_column_with_attributes(-1, "Filename", self.renderer0, text=0)
self.treeview.set_search_column(0)
self.treeview.set_search_entry(self.search_entry)
self.treeview.expand_all()

Я знаю, что TreeView имеет метод set_search_equal_func , где я могу изменить функцию сопоставления по умолчанию на свой собственный. Проблема в том, как изменить список при вводе в поле формы фильтра?

5
добавлено отредактировано
Просмотры: 1
de

2 ответы

Вы должны прочитать gtk.TreeModelFilter . Здесь вы можете прочитать очень полезный пример. Это C#, но очень легко «перевести» его на python:

http://www.mono-project.com/GtkSharp_TreeView_Tutorial#Filtering_Data

2
добавлено

Спасибо за эту ссылку на C#, это было очень полезно. Ключ состоит в использовании методов gtk.TreeModelFilter set_visible_func и refilter .

Код выглядит так:

Где-то в главном классе приложения:

def match_func(self, model, iterr, data=None):
    query = self.search_entry.get_buffer().get_text()
    value = model.get_value(iterr, 0)

    if query == "":
        return True
    elif query in value.lower():
        return True
    return False

def on_entry_refilter(self, widget, data=None):
    self.tree_filter.refilter()

Измененный код:

self.search_entry = gtk.Entry()
self.search_entry.connect('changed', self.on_entry_refilter)

self.tree_store = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_BOOLEAN)

for node, files in self.files_list:
    parent = self.tree_store.append(None, [node, True])
    for f in files:
        self.tree_store.append(parent, [f, True])

self.tree_filter = self.tree_store.filter_new()
self.tree_filter.set_visible_func(self.match_func)
self.treeview = gtk.TreeView(self.tree_filter)

self.renderer0 = gtk.CellRendererText()
self.treeview.insert_column_with_attributes(-1, "Filename", self.renderer0, text=0)
self.treeview.set_search_column(0)
self.treeview.set_search_entry(self.search_entry)
self.treeview.expand_all()
1
добавлено
+1, это действительно полезно. dziękuję!
добавлено автор Sardathrion, источник