gtk:在CellRendererCombo'已更改'信号上修改TreeView模型时遇到问题

时间:2010-08-20 20:31:13

标签: python gtk pygtk

我在给定列中有一个带有CellRendererCombo的树视图。我使用以下代码来设置列:

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)

treeViewTreeViewtreeViewModel是其模型,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注意到这一点:

  

请注意,只要更改树视图中显示的模型,树视图就会立即停止编辑操作。这意味着您很可能希望在组合单元格渲染器发出已编辑或编辑的编码信号之前不要更改模型。

但是没有提到代码会崩溃。在任何情况下,我都希望在单击组合框中的条目后,编辑停止,而不必按ENTER键或单击其他位置。我怎么能做到这一点?

2 个答案:

答案 0 :(得分:1)

在选择项目后立即结束编辑CellRendererCombo是一个两阶段的过程。

在第一阶段,您必须捕获组合本身,因为以后无法访问它。要捕获组合,请连接到editing-started CellRenderer信号。您可以在Glade中定义连接,也可以在代码中手动创建。

在第二阶段,在CellRendererCombo的focus-out-event信号处理程序中发出changed

以下是您修改的原始代码以演示:

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)

答案 1 :(得分:0)

我不确定,但我想获得答案的最快方法是搜索pygtk邮件列表,如果找不到类似的帖子,请尝试将其发布到邮件列表。

pygtk mailing list