Setting a single row of a CellRendererToggle to inconsistent
--
Music by Eric Matyas
https://www.soundimage.org
Track title: Puzzling Curiosities
--
Chapters
00:00 Question
02:49 Accepted answer (Score 4)
05:44 Answer 2 (Score 1)
06:45 Thank you
--
Full question
https://stackoverflow.com/questions/1476...
Question links:
https://python-gtk-3-tutorial.readthedoc...
Accepted answer links:
[here]: http://www.pygtk.org/docs/pygtk/class-gt...
[this]: http://faq.pygtk.org/index.py?quer
[this]: http://www.pygtk.org/pygtk2tutorial/sec-...
Answer 2 links:
[Gtk+ By Example]: http://en.wikibooks.org/wiki/GTK%2B_By_E...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #gtk #gtk3
#avk47
ACCEPTED ANSWER
Score 4
It is possible to set the property of one element via using a cell data function. Since I have done this only in C yet, I can only pass you the link to the documentation of PyGTK, I haven't seen the relevant docs for this feature for PyGObject yet.
For PyGTK is was documented here, this page gives you an example at the bottom, the use for cell data functions for PyGTK was also featured in this document.
If for example you would like to do the same as in Transmission, you could do the following: Since you receive the current iter as a parameter of the cell data function, you could loop through all of its children there and check the status of the children. You would then know which state to set at the parent node. Now the main point is that setting a property inside the cell data function will affect only this single cell, and not all elements of the treeview.
I can give you also a visual example for my own application:

I have the column "Value" in this treeview. If the value inside the column "Menu Element" is set to "enabled" and the value inside the column "Type" is "option", a checkbox is shown instead of text (I have highlighted such a row). The example image also shows an active search, which highlights search results. Both is possible with a cell data function to set the property of one element as you asked for in your question.
Edit
I've done some example code. The main point is that the cell property is always set for every cell. So not just "if ..., then set property" but "if, set property like this, else, set property like that". (It's based on the old PyGTK documentation, but it should clarify things anyway).
#!/usr/bin/env python
# example basictreeview.py
import pygtk
pygtk.require('2.0')
import gtk
class BasicTreeViewExample:
def set_status(self, column, cell, model, iter):
if 'inconsistent' in model.get_value(iter, 0):
cell.set_property('inconsistent',True)
else:
cell.set_property('inconsistent',False)
return
def delete_event(self, widget, event, data=None):
gtk.main_quit()
return False
def __init__(self):
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.window.set_title("Basic TreeView Example")
self.window.set_size_request(200, 200)
self.window.connect("delete_event", self.delete_event)
self.treestore = gtk.TreeStore(str)
for parent in range(4):
piter = self.treestore.append(None, ['parent %i' % parent])
for child in range(3):
if child == 1:
self.treestore.append(piter, ['consistent'])
else:
self.treestore.append(piter, ['inconsistent'])
self.treeview = gtk.TreeView(self.treestore)
self.tvcolumn0 = gtk.TreeViewColumn('Column 0')
self.tvcolumn1 = gtk.TreeViewColumn('Column 1')
self.treeview.append_column(self.tvcolumn0)
self.treeview.append_column(self.tvcolumn1)
self.text = gtk.CellRendererText()
self.toggle = gtk.CellRendererToggle()
self.tvcolumn0.pack_start(self.text, True)
self.tvcolumn1.pack_start(self.toggle, True)
self.tvcolumn0.add_attribute(self.text, 'text', 0)
self.tvcolumn1.set_cell_data_func(self.toggle, self.set_status)
self.window.add(self.treeview)
self.window.show_all()
def main():
gtk.main()
if __name__ == "__main__":
tvexample = BasicTreeViewExample()
main()
ANSWER 2
Score 1
I've had the same problem recently and found that a cell data function is not needed if you prefer to set the property directly from a column in your model. The updates needed in the code from the question that will make it happen should be as follows:
self.treeModel = Gtk.TreeStore(str, bool, bool)
...
column_toggle = Gtk.TreeViewColumn("Installer", renderer_toggle, active=1, inconsistent=2)
and then set the inconsistent value in the new column as needed.
As a hint about when to choose a cell data function or a new column in your model, take the following into account (Gtk+ By Example):
Your cell data function is going to be called every single time a cell in that (renderer) column is going to be rendered. Go and check how often this function is called in your program if you ever use one. If you do time-consuming operations within a cell data function, things are not going to be fast, especially if you have a lot of rows.