PyGtk:破坏组合框会导致错误

PyGtk : destroying combobox causes error

My aim is to destroy a combobox if one of its items is active.

I wrote this test code :

import pygtk
pygtk.require('2.0')
import gtk
import gobject

def remove(combobox):
  if 'OptionC' in combobox.get_active_text():
    combobox.destroy()

window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.set_default_size(800, 600)
window.set_title("Test")
window.connect("destroy", gtk.main_quit)
main_box = gtk.VBox(False, 2)
window.add(main_box)
nb = 3
for i in range(nb):
  liststore = gtk.ListStore(gobject.TYPE_STRING)
  combo = gtk.ComboBox(liststore)
  cell = gtk.CellRendererText()
  combo.pack_start(cell, True)
  combo.add_attribute(cell, 'text', 0)
  for text in ["OptionA-%d"%(i+1), "OptionB-%d"%(i+1), "OptionC-%d"%(i+1)]:
    combo.append_text(text)
    combo.set_active(0)
  combo.connect("changed", remove)
  main_box.pack_start(combo, expand=False)
window.show_all()
gtk.main()

If I open the popup of the combobox and click to select "OptionC", I have this message :

combo.py:29: Warning: invalid unclassed pointer in cast to `GObject' gtk.main()
combo.py:29: Warning: g_object_notify: assertion `G_IS_OBJECT (object)' failed gtk.main()
combo.py:29: Warning: g_object_set: assertion `G_IS_OBJECT (object)' failed gtk.main()

But if I select "OptionC" just scolling the combobox (without opening the popup), no error is encountered.

Thanks for your advice!

Answer : (working for pygtk version 2.24 but NOT for 2.16)

Replace this block :

liststore = gtk.ListStore(gobject.TYPE_STRING)
combo = gtk.ComboBox(liststore)
cell = gtk.CellRendererText()
combo.pack_start(cell, True)
combo.add_attribute(cell, 'text', 0)

By this function :

combo = gtk.combo_box_new_text()

您的代码很可靠,小部件已按应有的方式销毁。只需将其记为 pygtk/PyGObject 内存管理的一个怪癖即可。

它来是因为你使用了liststore。 新的 gtk 代码现在应该使用 combo_box_new_text()

这是您的代码:

for i in range(nb):
  combo = gtk.combo_box_new_text()
  cell = gtk.CellRendererText()
  combo.pack_start(cell, True)
  combo.add_attribute(cell, 'text', 0)
  for text in ["OptionA-%d"%(i+1), "OptionB-%d"%(i+1), "OptionC-%d"%(i+1)]:
    combo.append_text(text)
    combo.set_active(0)
  combo.connect("changed", remove)
  main_box.pack_start(combo, expand=False)
window.show_all()
gtk.main() 

那你为什么不使用

combobox.hide()

而不是

combobox.destroy()

看来销毁单个小部件并不是您真正应该做的事情。在大多数情况下,我不会破坏 Gtk 小部件,因为稍后您可能希望再次显示它们。