我在给定列中有一个带有 CellRendererCombo 的 TreeView 。我使用以下代码来设置列:
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
是一个TreeView
,treeViewModel
是它的模型,comboModel
是组合条目的模型仅包含两个字符串。
如果我运行代码,那么该组合将按预期工作,除了我第一次选择一个条目时出现以下错误:
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()
第二次我得到:
c:\python25\lib\site-packages\twisted\internet\gtk2reactor.py:255: Warning: inva
lid uninstantiatable type `<invalid>' in cast to `GObject'
gtk.main()
第三次程序崩溃了。如果我将连接线更改为:
crc.connect("edited", changed)
...那么代码就可以正常工作了。但是,该值仅在单击组合框外后才会更改,我宁愿每次选择一个对象时都更改它。我该怎么做后者?
编辑:我刚刚在 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.
不过,它没有提到代码会崩溃。在任何情况下,我都希望在单击组合框中的条目后停止编辑,而不必按 ENTER 键或单击其他地方。我怎样才能做到这一点?
最佳答案
在选择项目后立即结束 CellRendererCombo 的编辑是一个两阶段过程。
在第一阶段,您必须捕获组合本身,因为以后无法访问它。要捕获组合,请连接到 editing-started
CellRenderer 信号。您可以在 Glade 中定义连接或在代码中手动创建它。
在第二阶段,在 CellRendererCombo 的 changed
信号处理程序中发出一个 focus-out-event
。
这是您修改后的原始代码以演示:
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)
请注意,在较新版本的 GTK+ 中,您通常不会在 changed
信号处理程序中修改 TreeModel。您应该使用 edited
信号处理程序。
这是最终版本:
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)
关于python - gtk:在 CellRendererCombo 'changed' 信号上修改 TreeView 模型时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3534665/