python - gtk:在 CellRendererCombo 'changed' 信号上修改 TreeView 模型时遇到问题

标签 python gtk pygtk

我在给定列中有一个带有 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 是一个TreeViewtreeViewModel 是它的模型,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/

相关文章:

python - 如何找出 Python 对象丢失属性的原因/时间?

python : Generating a gzip string by returning chunks

python - `re` 模块匹配Python3中两对括号之间的文本

python - 如何通过 DeclarativeMeta 接口(interface)使用反射表?

c++11 - 如何在 Gtk::DrawingArea 区域绘制一条新线,同时保留之前已经绘制的线?

Python + GTK - 如何抑制警告

python subprocess popen同步命令

python - 如何使用 pygtk 在窗口中包含图像?

gtk - 与例如 GtkToolbar 相比,GtkToolbar 的优点/用途是什么?一个GtkHBox?

python - "WindowsError: [Error 2] The system cannot find the file specified"未解析