What I'm trying to do is dynamically change (via filter) list of strings. In my case it is list of files with paths stored in gtk.TreeStore
.
Example of expected effect (eg. Sublime Text 2 file searching Ctrl+P):
Data:
List of files (treeview):
Action: In filter field (Entry widget) user starts typing. After first character eg. 't' list should be updated like this:
Result:
List of files (treeview):
What I already have:
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()
I know that TreeView has a method set_search_equal_func
where I can change default matching function to my own. The problem is how can I change the list during typing in filter form field?
You must read about gtk.TreeModelFilter. Here you can read a very useful example. It's C#, but it's very easy to "translate" it to python:
http://www.mono-project.com/GtkSharp_TreeView_Tutorial#Filtering_Data
Thanks for that C# example link it was very useful. The key is to use gtk.TreeModelFilter
methods set_visible_func
and refilter
.
Code looks like that now:
Somewhere in main app class:
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()
Modified code:
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()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With