Reputation: 229361
I have a treeview with a CellRendererCombo in a given column. I use the following code to set up the column:
crc = gtk.CellRendererCombo()
crc.set_property('model', comboModel)
crc.set_property('text-column', 0)
crc.set_property('editable', True)
crc.set_property('has_entry', False)
cl = gtk.TreeViewColumn(ctitle, crc, text=i)
def changed(cell, path, newiter):
treeViewModel[path][0] = "HAH"
crc.connect("changed", changed)
treeView.append_column(cl)
treeView
is a TreeView
, treeViewModel
is its model, and comboModel
is the model for the combo entry containing just two strings.
If I run the code, then the combo works as expected, except that the first time I select an entry I get the following errors:
c:\python25\lib\site-packages\twisted\internet\gtk2reactor.py:255: Warning: inva
lid unclassed pointer in cast to `GObject'
gtk.main()
c:\python25\lib\site-packages\twisted\internet\gtk2reactor.py:255: Warning: g_ob
ject_notify: assertion `G_IS_OBJECT (object)' failed
gtk.main()
On the second time I get:
c:\python25\lib\site-packages\twisted\internet\gtk2reactor.py:255: Warning: inva
lid uninstantiatable type `<invalid>' in cast to `GObject'
gtk.main()
and on the third time the program crashes. If I change the connect line to:
crc.connect("edited", changed)
...then the code works fine. However, the value only changes after clicking out of the combo box, and I'd rather have it change every time an object is selected. How can I do the latter?
EDIT: I just noticed this in the API docs for pygtk:
Note that as soon as you change the model displayed in the tree view, the tree view will immediately cease the editing operating. This means that you most probably want to refrain from changing the model until the combo cell renderer emits the edited or editing_canceled signal.
It doesn't mention that the code would crash, though. In any case, I'd like it that after clicking an entry in the combobox, editing stops, without having to press ENTER or click somewhere else. How can I accomplish that?
Upvotes: 4
Views: 1616
Reputation: 11
Ending editing of a CellRendererCombo immediately after an item is selected is a two stage process.
In the first stage, you must capture the combo itself, since it is not accessible later. To capture the combo, connect to the editing-started
CellRenderer signal. You may define the connection in Glade or create it manually in code.
In the second stage, emit a focus-out-event
in a changed
signal handler for CellRendererCombo.
Here is your original code modified to demonstrate:
comboEditable = None
crc = gtk.CellRendererCombo()
crc.set_property('model', comboModel)
crc.set_property('text-column', 0)
crc.set_property('editable', True)
crc.set_property('has_entry', False)
cl = gtk.TreeViewColumn(ctitle, crc, text=i)
def changed(cell, path, newiter):
treeViewModel[path][0] = "HAH"
e = gtk.gdk.Event(gtk.gdk.FOCUS_CHANGE)
e.window = treeView.window
e.send_event = True
e.in_ = False
comboEditable.emit('focus-out-event', e)
def started(cell, editable, path):
# Or to make life more predictable, use a class and set self.comboEditable
global comboEditable
comboEditable = editable
crc.connect('changed', changed)
crc.connect('editing-started', started)
treeView.append_column(cl)
Note that in more recent versions of GTK+, you don't ordinarily modify the TreeModel in the changed
signal handler. You should use the edited
signal handler.
Here is the final version:
comboEditable = None
crc = gtk.CellRendererCombo()
crc.set_property('model', comboModel)
crc.set_property('text-column', 0)
crc.set_property('editable', True)
crc.set_property('has_entry', False)
cl = gtk.TreeViewColumn(ctitle, crc, text=i)
def changed(cell, path, newiter):
e = gtk.gdk.Event(gtk.gdk.FOCUS_CHANGE)
e.window = treeView.window
e.send_event = True
e.in_ = False
comboEditable.emit('focus-out-event', e)
def started(cell, editable, path):
# Or to make life more predictable, use a class and set self.comboEditable
global comboEditable
comboEditable = editable
def edited(cell, path, newtext):
treeViewModel[path][columnNumber] = newText
crc.connect('changed', changed)
crc.connect('editing-started', started)
crc.connect('edited', edited)
treeView.append_column(cl)
Upvotes: 1
Reputation: 618
i'm not sure, but i guess the fastest way to get an answer is to search the pygtk mailing list, and if you cant find a similar post, try posting it to the mailing list.
Upvotes: 0